提问人:Regus Pregus 提问时间:2/14/2022 最后编辑:Brian BiRegus Pregus 更新时间:2/14/2022 访问量:1058
std::basic_string<T>::size_type 导致 C++20 模式下的编译错误 [重复]
std::basic_string<T>::size_type causes compile error in C++20 mode [duplicate]
问:
下面是 MSVC 2022 在 C++17 模式下编译但在 C++20 模式下失败的简单代码:
template <typename T>
void foo()
{
std::basic_string<T>::size_type bar_size; //This fails to compile in C++20
}
在 C++20 模式下报告的错误无助于解释原因:error C3878: syntax error: unexpected token 'identifier' following 'expression'
有趣的是,它只发生在模板化函数中,这个反例在 C++20 模式(以及 C++17)中编译得很好:
void baz()
{
std::basic_string<char>::size_type bar_size;
}
到目前为止,我可以解决问题的唯一方法是使用 auto 而不是显式数据类型,例如:
template <typename T>
void foo()
{
std::basic_string<T> bar;
auto bar_size = bar.size();
}
但我真的很想了解 C++20 与 C++17 相比发生了什么变化,导致此语法无效,而不仅仅是盲目地应用解决方法补丁。
答:
3赞
Vlad from Moscow
2/14/2022
#1
用
typename std::basic_string<T>::size_type bar_size;
该名称是依赖名称。size_type
评论
1赞
pm100
2/14/2022
您能否解释一下为什么会起作用,这与指示的副本有什么关系,以及 17 到 20 之间发生了什么变化 - 请
2赞
Vlad from Moscow
2/14/2022
@pm100 什么都没有改变。如果没有关键字 typename,编译器会将记录视为表达式。也许编译器更符合 C 标准
0赞
Regus Pregus
2/14/2022
@pm100 事实上,C++17 模式下的 MSVC 似乎不符合标准,因为在这种情况下,我可以在不使用 typename 关键字的情况下逃脱。当 MS 引入 C++20 支持时,他们在 C++20 模式下修复了它,但没有在 C++17 模式下修复它。也许我应该向 MS 提交错误报告......
0赞
Sebastian
2/14/2022
它可能是为了不破坏依赖它的现有代码。
评论
std::basic_string<T>::size_type bar_size;
在标准 C++ 中永远无效。在 C++20 模式下,MSVC 默认启用/permissive-
,这会正确标记此错误。