为什么在VS2015中模板相关的嵌套类型名称中不需要typename关键字?
Why typename keyword is not needed in template dependent nested type names in VS2015?
我正在阅读有关typename
在模板编程中的用法C++例如此问答(。对我来说,似乎在使用依赖嵌套类型名称时,我们应该使用typename
以避免解析歧义。我还在苏格兰迈耶斯的书有效C++,项目#42上检查了这一点。
但对我来说奇怪的是,书中的相同示例在没有typename
的情况下工作。这是代码:
template<class C>
void Print2nd(const C & cont)
{
if (cont.size() >= 2)
{
C::const_iterator * iter1 = new C::const_iterator(cont.begin()); // why typename is NOT needed?
C::const_iterator iter2 = cont.begin(); // why typename is NOT needed?
(*iter1)++;
iter2++;
int value1 = **iter1;
int value2 = *iter2;
std::cout << "The value of 2nd with pointer is: " << value1 << std::endl;
std::cout << "The value of 2nd without pointer is: " << value2 << std::endl;
}
}
int main()
{
std::vector<int> vect = {1,2,3,4,5,6};
Print2nd(vect);
return 0;
}
我正在使用VS2015。那么,问题是为什么在这种情况下不需要typename
?最近的C++编译器是否有任何升级以避免在这样的上下文中使用typename
?还是我在代码中做错了?
更新1:由于@FrançoisAndrieux评论,VS2008和VS2010似乎也发生了同样的事情,如本问答中所述。
在 c++20 中,那里不需要typename
。 在某些上下文中,不再需要typename
,因为语法上任何内容都必须有一个类型。
特别:
出现在类型 ID中的限定名称,其中最小的封闭类型 ID 为:
- 新表达式中不用括号括起来的类型;
引用的来源不是直接来自标准,但非常可靠。
在 c++20 之前,那里需要typename
;它将被解析为一个值,new value
不是有效的语法。 在 c++20 中,typename
在该上下文中是可选的。
现在,visual-studio-2015 没有 c++20 功能;你看到的是 MSVC 未能正确实现 c++11/c++14/c++17,而不是 c++20 扩展。
需要typename
;示例程序格式不正确。如果编译器未诊断问题,则不符合标准。正确的版本是:
typename C::const_iterator * iter1 = new typename C::const_iterator(cont.begin());
// ^^^^^^^^ this one only required until C++20
typename C::const_iterator iter2 = cont.begin();
标准报价(C++17草案(:
[温度]
模板声明或定义中使用的依赖于模板参数的名称假定不命名类型,除非适用的名称查找找到类型名称或该名称由关键字
typename
限定。
C::const_iterator
取决于模板参数C
,所以除非使用typename
,否则不应假定它是类型名。我认为该语句应该解释为乘法运算,但右手操作数是未声明的标识符,因此格式不正确。
C++20 引入了允许从新表达式(最新草稿(中删除typename
的规则:
[温度]
如果限定名称出现在类型 ID、新类型 ID 或定义类型 ID 中,并且最小的封闭类型 ID、新类型 ID 或定义类型是新类型 ID、定义类型 ID、尾随返回类型、模板的类型参数的默认参数或static_cast、const_cast、reinterpret_cast或dynamic_cast的类型 ID,则称限定名称在仅类型 ID上下文中。
您可能希望创建类型别名以提高可读性:
using const_iterator = typename C::const_iterator;
或者你可以只使用auto
:
auto it = cont.begin();
附言动态分配迭代器几乎没有意义。
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 是否有类似std::lower_bound的函数,而不需要排序/分区输入
- 为什么output_editor Concept不需要output_e迭代器标记
- 在除法中不需要四舍五入
- 与C代码相比,为什么C++代码不需要"#define _POSIX_C_SOURCE 200809L"?
- 为什么返回类型中需要typename?C++
- 将值从另一个数组写入数组,不包括不需要的值 C++
- C++ 写入路径名中包含不需要的空字符的文件
- 是否有必要获取锁并在不需要唤醒线程时通知condition_variable?
- 使用 assimp 加载模型 - 不需要提升?
- 为什么转换函数声明不需要至少一个定义类型说明符
- 返回不需要的值的二叉搜索程序
- 当我不需要数据库中的所有值时,如何部分初始化 c++ 对象?
- C++:用户输入会产生不需要的行为
- 为什么不需要在 C++20 中的依赖类型之前指定"typename"?
- 为什么在以下情况下不需要为依赖类型使用typename
- 为什么在VS2015中模板相关的嵌套类型名称中不需要typename关键字?
- 为什么嵌套类型的基类不需要"typename"?
- 在不需要时使用"template"和"typename"消除歧义器
- 为什么在Visual Studio 2008/2010中不需要typename __