【发布时间】:2020-11-16 00:04:06
【问题描述】:
使用以下程序(它是我正在试验的较大程序的摘录),我收到一条错误消息,似乎与 fixed_string 的构造函数有关
#include <string>
#include <cstring>
template<std::size_t N>
struct fixed_string {
static const constexpr std::size_t size__ = N;
constexpr fixed_string(char const* s) :
buf("") {
for (std::size_t i = 0; i <= N; ++i)
buf[i] = s[i];
}
constexpr operator char const*() const {
return buf;
}
constexpr bool operator==(const char* other) const {
return ::strncmp(buf, other, N) == 0;
}
template<std::size_t M>
constexpr bool compare(const fixed_string<M>& other) const {
return (N == M && ::strncmp(buf, other.buf, N) == 0) ? std::true_type(): std::false_type();
}
char buf[N + 1];
};
template<std::size_t N>
fixed_string(char const (&)[N]) -> fixed_string<N - 1>;
////////////////////////////////////////////
template<fixed_string TARGET_NAME, fixed_string THIS_NAME>
concept NameMatches = (TARGET_NAME.compare(THIS_NAME));
template<fixed_string NAME, typename TYPE>
class Member {
public:
static const constexpr fixed_string name__ { NAME };
public:
template<fixed_string TARGET_NAME>
const TYPE& get() const requires NameMatches<TARGET_NAME, TYPE::name__> const {
return member_;
}
protected:
TYPE member_;
};
template<typename ... MEMBERS>
class Container: public MEMBERS... {
};
错误信息是:
../src/test-concepts.cpp:43:35: error: class template argument deduction failed:
43 | const TYPE& get() const requires NameMatches<TARGET_NAME, TYPE::name__> const {
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../src/test-concepts.cpp:43:35: error: no matching function for call to ‘fixed_string(fixed_string<...auto...>)’
../src/test-concepts.cpp:8:12: note: candidate: ‘template<long unsigned int N> fixed_string(const char*)-> fixed_string<N>’
8 | constexpr fixed_string(char const* s) :
| ^~~~~~~~~~~~
../src/test-concepts.cpp:8:12: note: template argument deduction/substitution failed:
../src/test-concepts.cpp:43:35: note: couldn’t deduce template parameter ‘N’
43 | const TYPE& get() const requires NameMatches<TARGET_NAME, TYPE::name__> const {
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../src/test-concepts.cpp:5:8: note: candidate: ‘template<long unsigned int N> fixed_string(fixed_string<N>)-> fixed_string<N>’
5 | struct fixed_string {
| ^~~~~~~~~~~~
../src/test-concepts.cpp:5:8: note: template argument deduction/substitution failed:
../src/test-concepts.cpp:43:35: note: mismatched types ‘fixed_string<N>’ and ‘fixed_string<...auto...>’
43 | const TYPE& get() const requires NameMatches<TARGET_NAME, TYPE::name__> const {
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../src/test-concepts.cpp:28:1: note: candidate: ‘template<long unsigned int N> fixed_string(const char (&)[N])-> fixed_string<(N - 1)>’
28 | fixed_string(char const (&)[N]) -> fixed_string<N - 1>;
| ^~~~~~~~~~~~
../src/test-concepts.cpp:28:1: note: template argument deduction/substitution failed:
../src/test-concepts.cpp:43:35: note: mismatched types ‘const char [N]’ and ‘fixed_string<...auto...>’
43 | const TYPE& get() const requires NameMatches<TARGET_NAME, TYPE::name__> const {
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../src/test-concepts.cpp:43: confused by earlier errors, bailing out
这是使用模板的项目的一部分,该模板重载给定函数(在本例中为get),对于该模板,只有一个满足约束的合适候选者。约束操作的值是名称 - 字符串文字 - 不是 const 字符串变量,它作为非类型参数传递给模板的实例化:类似于:
Container<Member<"fred", std::string>, Member<"bert", int>, Member<"alfie", bool>> some_values;
我希望能够使用类似的东西检索一个值
int result = some_values.get<"bert">();
我很难找到有关模板的“<...auto...>”专业化的大量信息。我认为这是gcc 用于常量、非类型值的内部表示。
错误消息指出我缺少适合fixed_string 的重载构造函数。这应该是什么?
【问题讨论】:
-
无关:
operator==(const char*)和compare似乎不一致。为什么N == M在compare中必须是true?现在可以static_cast<const char*>(the_rhs_fixed_string)并使用operator==(const char*)并获得true其中compare将返回false。 -
Compare 仅用于一个特定目的:确保两个字符串在约束的上下文中绝对相同。但是你的评论很好 - 我会玩它。
标签: c++ templates c++20 c++-concepts