代码之家  ›  专栏  ›  技术社区  ›  Matt Joiner

在C++中传递非const引用

  •  13
  • Matt Joiner  · 技术社区  · 14 年前

    在以下代码行中:

    bootrec_reset(File(path, size, off), blksize);
    

    使用原型调用函数:

    static void bootrec_reset(File &file, ssize_t blksize);
    

    我收到此错误:

    libcpfs/mkfs.cc:99:53:错误:从“file”类型的右值初始化“file&”类型的非常量引用无效

    libcpfs/mkfs.cc:30:13:错误:传递“void bootrec_reset(file&,ssize_t)”的参数1时

    我知道你不能传递非常量引用( const & )按标准计算。但是,MSVC允许您执行此操作(请参见 this question ) This question 试图解释原因,但答案毫无意义,因为他使用的是文字,这是一个角落案件,显然应该被禁止。

    在给定的示例中,可以清楚地看到将发生以下事件顺序(就像在MSVC中那样):

    1. File 将调用的构造函数。
    2. 参考 文件 blksize ,被推到堆栈上。
    3. bootrec_reset 利用 file .
    4. 从返回后 bootrec_重置 ,临时 文件 被摧毁。

    有必要指出 文件 引用必须是非常量,因为它是对文件的临时句柄,在该文件上调用非常量方法。而且我不想通过 文件 的构造函数参数 bootrec_重置 在那里建造,我也没有看到任何理由手动建造和摧毁 文件 调用方中的对象。

    所以我的问题是:

    1. C++标准以这种方式禁止非const引用有什么理由?
    2. 如何强制GCC允许此代码?
    3. 即将到来的C++0X标准是否会改变这一点,或者新的标准会给我一些更合适的东西,例如所有关于RValk引用的胡言乱语?
    7 回复  |  直到 14 年前
        1
  •  8
  •   j_random_hacker    14 年前

    this comp.lang.c++.moderated thread

     void inc( long &x ) { ++x; }
    
     void test() {
         int y = 0;
         inc( y );
         std::cout << y;
     } 
    

    long &x inc() long y

        2
  •  6
  •   Cheers and hth. - Alf    14 年前

    export

    bootrec_reset(File(path, size, off), blksize);
    

    File f(path, size, off);
    bootrec_reset(f, blksize);
    

    bootrec_reset bootrec_reset(tempref(File(path, size, off)), blksize); tempref

        3
  •  6
  •   fredoverflow    14 年前

    template <typename T>
    T& as_lvalue(T&& x)
    {
        return x;
    }
    
    // ...
    
    bootrec_reset(as_lvalue(File(path, size, off)), blksize);
    
        4
  •  2
  •   Fabian Giesen    14 年前
    1. std::vector<type>().swap(some_vector);
    2. File &&
        5
  •  1
  •   Ben Voigt    14 年前

    #include <iostream>
    
    template<typename T>
    void func(T& t)
    {
        int& r = t;
        ++r;
    }
    
    int main(void)
    {
        int i = 4;
        long n = 5;
        const int& r = n;
    
        const int ci = 6;
        const long cn = 7;
    
        //int& r1 = ci;
        //int& r2 = cn;
    
        func(i);
        //func(n);
    
        std::cout << r << std::endl;
    }
    

    func(i) func(n)

    {
      File ftemp(path, size, off);
      bootrec_reset(ftemp, blksize);
    }
    

        6
  •  1
  •   Puppy    12 年前

    static void bootrec_reset(File &&file, ssize_t blksize) {
        return bootrec_reset(file, blksize);
    }
    

        7
  •  0
  •   Neil    9 年前

    class File /* ... */ {
    public:
      File* operator&() { return this; }
    /* ... */
    };
    /* ... */
    bootrec_reset(*&File(path, size, off), blksize);