提问人:glades 提问时间:10/4/2022 更新时间:10/4/2022 访问量:224
错误:std::variant 的模板参数列表中的类型/值不匹配
error: type/value mismatch in template parameter list for std::variant
问:
如果类是模板化的,则以下代码不起作用。所以我的猜测是我必须把说明符放在某物前面,但我真的不知道在哪里?我尝试将其放在变体定义中的state::base和state::error类型前面,但这不起作用。我把它放在哪里,为什么?some_class
template
#include <variant>
template <typename T>
class some_class
{
void do_something() {
struct state {
struct base{};
struct error{};
};
std::variant<state::base, state::error> fsm{};
}
};
int main() {}
错误:
<source>:12:47: error: type/value mismatch at argument 1 in template parameter list for 'template<class ... _Types> class std::variant'
12 | std::variant<state::base, state::error> fsm{};
| ^
<source>:12:47: note: expected a type, got 'some_class<T>::do_something()::state::base'
<source>:12:47: error: type/value mismatch at argument 1 in template parameter list for 'template<class ... _Types> class std::variant'
<source>:12:47: note: expected a type, got 'some_class<T>::do_something()::state::error'
答:
3赞
user17732522
10/4/2022
#1
编译器认为 和 是依赖的(基于模板参数),在这种情况下,它们需要前缀 with,以便在分析类模板定义时将它们视为类型。state::base
state::error
typename
然而,从直觉上看,这些名称/类型似乎不应该是依赖的。尽管对于封闭类模板的每个专用化,类型是不同的类型,但可以保证,对于封闭模板的每个实例化,该类型将始终在函数定义中命名和引用已知类型。这不能改变,例如通过显式或部分专业化。state::base
这似乎是一个悬而未决的CWG问题(CWG 2074)。该标准目前没有说这些名称是依赖的。仅当本地类包含依赖类型时,它们才会具有依赖性(请参阅 [temp.dep.type]/9.5),但在您的情况下,它们不会这样做。尽管如此,似乎一些编译器认为这些类型是依赖的。
因此,您的解决方案是为它们添加前缀,即使根据标准可能不需要或不打算这样做。typename
评论
0赞
glades
10/4/2022
谢谢你的解释。我认为用户会从范围的角度思考,而在这种情况下编译器不会这样做。我同意你的看法,这不是很直观。typename 解决了这个问题。
评论