std::basic_string<T>::size_type 导致 C++20 模式下的编译错误 [重复]

std::basic_string<T>::size_type causes compile error in C++20 mode [duplicate]

提问人:Regus Pregus 提问时间:2/14/2022 最后编辑:Brian BiRegus Pregus 更新时间:2/14/2022 访问量:1058

问:

下面是 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 相比发生了什么变化,导致此语法无效,而不仅仅是盲目地应用解决方法补丁。

C++ 模板 C++20 依赖项名称

评论

0赞 StoryTeller - Unslander Monica 2/14/2022
此类声明没有任何变化。这只是 MSVC 的合规之旅......参差不齐。
1赞 cpplearner 2/14/2022
std::basic_string<T>::size_type bar_size;在标准 C++ 中永远无效。在 C++20 模式下,MSVC 默认启用 /permissive-,这会正确标记此错误。

答:

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
它可能是为了不破坏依赖它的现有代码。