c++ - 为什么在推导类型时去除模板参数的限定符?

标签 c++ visual-studio visual-studio-2008 templates

在使用 Microsoft VisualStudio 2008 构建一个小示例程序时,我注意到关于传递给模板的类型的推导有一件奇怪的事情。考虑这个例子:

template<class T>
void f( T v ) {
    x; // trigger a compile error
    (void)v;
}

template<class T>
void g( T v ) {
    f( v );
}

void h() {
  int i;
  g<const int &>( i );
}

使用 cl/c foo.cpp 编译此示例会产生编译错误(如预期的那样)。有趣的是“T”模板参数的值。这是 VisualStudio 2008 打印的内容:

mini.cpp(3) : error C2065: 'x' : undeclared identifier
        mini.cpp(9) : see reference to function template instantiation 'void f<int>(T)' being compiled
        with
        [
            T=int
        ]
        mini.cpp(14) : see reference to function template instantiation 'void g<const int&>(T)' being compiled
        with
        [
            T=const int &
        ]

请注意在 g 中,参数的类型是 const int & 但在 f 中它只是 int。显然,在推导实例化 f 模板时要使用的类型时,引用 const 部分被删除了。调整示例以便调用 f

f<T>( v );

fg中,类型都是const int &。这是为什么?这是指定的行为吗?我 secret 地依赖传递给 fv 函数参数的类型,但显然不是。

最佳答案

答案是虽然变量 v 的类型是 const int &,但是 expression v 是一个类型为 const int 的左值表达式。

litb 提供了文本 (5/6):“如果一个表达式最初具有“对 T 的引用”类型(8.3.2、8.5.3),则在任何进一步分析之前将类型调整为“T”,该表达式指定由引用表示的对象或函数,并且该表达式是一个左值。”

“参数”是“函数调用表达式中由括号包围的逗号分隔列表中的表达式”(1.3.1)。所以在 14.8.2.1 中:

  • “调用的相应参数类型(称之为A)”是const int
  • “如果 A 是 cv 限定类型,则类型推导将忽略 A 类型的顶级 cv 限定符”(因此,int)。
  • “推导过程试图找到使推导的 A 与 A 相同的模板参数值”(所以 T 是 int)

关于c++ - 为什么在推导类型时去除模板参数的限定符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4164451/

相关文章:

c++ - 尝试将 time_t 数据类型转换为 (dd/mm/yyyy) 格式 C++

c++ - 如何在C++中使用系统功能执行具有多字节字符的命令

c++ - 返回类型 '?:'(三元条件运算符)

visual-studio - 使用 Tortoise 向 subversion 存储库添加解决方案时,如何避免添加不必要的文件

c++ - 基于范围的 for 循环会抛出带有数组参数的编译器错误

c# - 无法将必备组件放在与我的应用程序相同的位置

c++ - 如何调试/修复访问冲突(堆损坏)

c++ - 反击没有给出预期的结果

c# - 如何在 C# 中添加启动画面?

c# - 如何在 StyleCop 中执行私有(private)方法的文档?