【问题标题】:constant references with typedef and templates in c++c++中typedef和模板的常量引用
【发布时间】:2011-04-17 15:35:16
【问题描述】:

听说临时对象只能分配给常量引用。

但是这段代码出错了

#include <iostream.h>    
template<class t>
t const& check(){
  return t(); //return a temporary object
}    
int main(int argc, char** argv){

const int &resCheck = check<int>(); /* fine */
typedef int& ref;
const ref error = check<int>(); / *error */
return 0;
}

得到的错误是invalid initialization of reference of type 'int&amp;' from expression of type 'const int'

【问题讨论】:

    标签: c++ templates reference constants temporary


    【解决方案1】:

    这个:

    typedef int& ref;
    const ref error;
    

    不做你认为它做的事。请考虑:

    typedef int* pointer;
    typedef const pointer const_pointer;
    

    const_pointer 的类型是int* const不是 const int *。也就是说,当您说const T 时,您是在说“创建一个 T 不可变的类型”;所以在前面的例子中,指针(不是指针)是不可变的。

    不能引用constvolatile。这个:

    int& const x;
    

    没有意义,所以在引用中添加 cv-qualifiers 没有任何效果。

    因此,error 的类型为 int&amp;。您不能为其分配const int&amp;


    您的代码中还有其他问题。例如,这肯定是错误的:

    template<class t>
    t const& check()
    {
        return t(); //return a temporary object
    }
    

    你在这里所做的是返回一个对临时对象的引用当函数返回时它的生命周期结束。也就是说,如果你使用它,你会得到未定义的行为,因为在引用处没有对象。这并不比:

    template<class t>
    t const& check()
    {
        T x = T();
        return x; // return a local...bang you're dead
    }    
    

    更好的测试是:

    template<class T>
    T check()
    {
        return T();
    }
    

    函数的返回值是一个临时值,所以你仍然可以测试你确实可以将临时值绑定到常量引用。

    【讨论】:

      【解决方案2】:

      由于英语语法的运作方式,这对于说英语的人来说是一个非常常见的错误。

      我认为非常不幸的是,C++ 语法允许两者兼有:

      const int // immutable int
      int const // immutable int
      

      意思相同。

      它并没有让它变得更容易,真的,并且不可组合,因为:

      const int* // mutable pointer to immutable int
      int* const // immutable pointer to mutable int
      

      当然没有相同的意思。

      正如@GMan 所解释的那样,不幸的是,这对你来说很重要。

      如果您希望将来避免此类错误,请养成在 右侧 限定您的类型(constvolatile)的习惯,那么您将能够将typedef 视为简单的文本替换。

      【讨论】:

        【解决方案3】:

        您的代码出错,因为 const ref error 中的 const 限定符被忽略了,因为 8.3.2/1

        Cv 限定引用格式错误,除非通过使用 typedef (7.1.3) 或模板类型参数 (14.3) 引入 cv 限定符,在这种情况下 cv 限定符被忽略。`

        所以error 的类型为int&amp; 而不是const int&amp;

        【讨论】:

          【解决方案4】:

          为了与Right Left Rule 保持一致,我更喜欢像这样使用“cv”限定符。

          int const x = 2; // x is a const int (by applying Right Left rule)
          
          int const *p = &x;  // p is a pinter to const int
          

          在你的例子中,我会这样写const ref error = check&lt;int&gt;();

          ref const error = check<int>(); // parsed as error is a const reference to an integer
          

          正如@Prasoon Saurav 指出的那样,通过 typedef 引入 cv 限定符时会被忽略,因为正如@GMan 还说的那样,cv 限定的引用格式不正确。

          因此声明如下,当然是错误的。

             int &error = check<int>(); 
          

          查看this了解更多信息。

          【讨论】:

          • 由于帖子中提供的链接,这值得 +1。
          【解决方案5】:

          这是编译好的:

          typedef const int& ref; 参考错误 = 检查();

          VC++ 编译器对您的错误给出了一些解释:限定符应用于引用类型;忽略。引用类型必须声明为常量,常量不能以后应用。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-08-07
            • 1970-01-01
            • 2016-08-23
            • 1970-01-01
            • 1970-01-01
            • 2012-10-10
            • 1970-01-01
            相关资源
            最近更新 更多