代码之家  ›  专栏  ›  技术社区  ›  Frerich Raabe

为什么在推导类型时去掉模板参数的限定符?

  •  7
  • Frerich Raabe  · 技术社区  · 15 年前

    在用微软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型 调用方式如下

    f<T>( v );
    

    类型是 两者都有 f型 . 为什么?这是特定的行为吗?我暗地里依赖 v f型

    2 回复  |  直到 15 年前
        1
  •  6
  •   Steve Jessop    15 年前

    答案是尽管变量 v 具有类型 const int & ,和 是具有类型的左值表达式 const int .

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

    • “调用的相应参数类型(call it A)”是 .
    • int
    • “演绎过程试图找到模板参数值,使演绎值与A相同”(因此T是 内景
        2
  •  1
  •   MSalters    15 年前

    http://accu.org/index.php/journals/409 是一篇相当广泛的文章,但它解释了这个过程。从模板参数,参数类型 P 是派生的,并且与参数类型匹配 A 一个 派生自函数参数:对于非数组类型,只需剥离引用。因此,如果参数的类型是 int& ,然后是目标类型 只是 int

    原因很简单:因为标准告诉我们。理由是什么?碰巧,这篇文章的脚注也指出了这一点。在你的例子中, typeid(v)==typeid(const int) . 在非左值上下文中使用时,引用类型的行为类似于非引用类型。