Tôi đang cố gắng tạo một hàm constexpr sẽ nối một số mảng char tùy ý bằng cách làm việc từ câu trả lời sau của Xeo, nối hai mảng char.constexpr để nối hai hay nhiều chuỗi char
https://stackoverflow.com/a/13294458/1128289
#include <array>
template<unsigned... Is> struct seq{};
template<unsigned N, unsigned... Is>
struct gen_seq : gen_seq<N-1, N-1, Is...>{};
template<unsigned... Is>
struct gen_seq<0, Is...> : seq<Is...>{};
template<unsigned N1, unsigned... I1, unsigned N2, unsigned... I2>
constexpr std::array<char const, N1+N2-1> concat(char const (&a1)[N1], char const (&a2)[N2], seq<I1...>, seq<I2...>){
return {{ a1[I1]..., a2[I2]... }};
}
template<unsigned N1, unsigned N2>
constexpr std::array<char const, N1+N2-1> concat(char const (&a1)[N1], char const (&a2)[N2]){
return concat(a1, a2, gen_seq<N1-1>{}, gen_seq<N2>{});
}
nỗ lực của tôi vậy, đến nay:
#include <iostream>
#include <array>
template<unsigned... Is> struct seq{};
template<unsigned N, unsigned... Is>
struct gen_seq : gen_seq<N-1, N-1, Is...>{};
template<unsigned... Is>
struct gen_seq<0, Is...> : seq<Is...>{};
template<unsigned N1, unsigned... I1, unsigned N2, unsigned... I2>
constexpr const std::array<char, N1+N2-1>
concat_impl(
const char (&a1)[N1], const char (&a2)[N2], seq<I1...>, seq<I2...>)
{
return {{ a1[I1]..., a2[I2]... }};
}
template<unsigned N1, unsigned N2>
constexpr const std::array<char, N1+N2-1>
concat(const char (&a1)[N1], const char (&a2)[N2])
{
return concat_impl(a1, a2, gen_seq<N1-1>{}, gen_seq<N2>{});
}
template<unsigned N1, unsigned N2, class... Us>
constexpr auto
concat(const char(&a1)[N1], const char(&a2)[N2], const Us&... xs)
-> std::array<char, N1 + decltype(concat(a2, xs...))::size() - 1>
{
return concat(a1, concat(a2, xs...));
}
int main()
{
auto const s = concat("hi ", "there!");
std::cout << s.data() << std::endl;
// compile error:
auto const t = concat("hi ", "there ", "how ", "are ", "you?");
std::cout << t.data() << std::endl;
}
Cả gcc 4.9 và kêu vang 3.5 cho lỗi chỉ ra rằng không có chức năng phù hợp với các concat
bên trong biểu decltype
có thể được tìm thấy.
kêu vang:
error: no matching function for call to 'concat'
auto const t = concat("hi ", "there ", "how ", "are ", "you?");
^~~~~~
ctconcat.cpp:105:16: note: candidate template ignored: substitution failure [with N1 = 4, N2 = 7, Us = <char [5], char [5], char [5]>]: no matching function for call to 'concat'
constexpr auto concat(const char(&a1)[N1], const char(&a2)[N2], const Us&... xs) -> std::array<char, N1 + decltype(concat(a2, xs...))::size() - 1>
^ ~~~~~~
ctconcat.cpp:62:43: note: candidate function template not viable: requires 2 arguments, but 5 were provided
constexpr const std::array<char, N1+N2-1> concat(const char (&a1)[N1], const char (&a2)[N2])
^
1 error generated.
Các lỗi từ gcc và Clang cả chỉ ra rằng thứ hai mẫu concat
chức năng không phải là một ứng cử viên cho concat
trong biểu thức decltype
. Chỉ có mẫu đầu tiên được xem xét. Tại sao vậy và làm thế nào để khắc phục điều này?
Edit: câu hỏi có liên quan về việc tại sao decltype
không thể được sử dụng một cách đệ quy
trailing return type using decltype with a variadic template function
Tôi có thiếu một cái gì đó nhưng những gì xảy ra với ' "hi" "có"' mà cũng sẽ nối các dây? –
Theo như tôi có thể thấy, đây là một vấn đề tra cứu tên cơ bản: trong kiểu dấu trả về, hàm (template) chưa được khai báo và do đó không được tìm thấy bằng tra cứu không đủ tiêu chuẩn. ADL có thể tìm thấy nó, mặc dù. – dyp
@dyp Ah, có ý nghĩa. ADL có thể tìm thấy nó? Làm sao? Chờ đã, không ... Tôi lại bối rối ... vấn đề xảy ra khi khởi tạo, không phải là tuyên bố. – Praxeolitic