C ++ 11右值引用和常量

时间:2014-03-21 15:17:00

标签: c++11 rvalue-reference

以下代码是一个类似于元组的类的片段,可以在元组中获取对给定类型的引用,或者如果找不到该类型,则会返回提供的默认值。

如果默认值是左值,则必须返回引用,如果默认值是右值,则必须返回右值。

以下代码说明了我遇到的问题:

struct Foo {
    Foo(int d) : data(d) {}

    template <typename T, typename TT>
    const TT get_or_default(TT&& t) const {
        return data;
    }

    template <typename T, typename TT>
    TT get_or_default(TT&& t) {
        return data;
    }

    int data;
};

int main(int argc, char* argv[]) {
    int i = 6;
    const Foo foo1(5);
    Foo foo2(5);

    // compile error
    foo1.get_or_default<int>(i);

    // works
    foo1.get_or_default<int>(5);
    foo2.get_or_default<int>(i) = 4;
    foo2.get_or_default<char>('a');

    return 0;
}

编译时,我收到以下错误:

cxx.cxx:6:20: error: binding of reference to type 'int' to a value of type 'const int' drops qualifiers
            return data;
                   ^~~~
cxx.cxx:23:14: note: in instantiation of function template specialization 'Foo::get_or_default<int, int &>' requested here
        foo1.get_or_default<int>(i);
             ^
1 error generated.

1 个答案:

答案 0 :(得分:1)

当函数参数的类型为T&&,其中T是模板参数时,模板参数推导有一个特殊规则。该规则是:

  

如果函数参数是U类型的左值,则在这种情况下使用U&代替U进行类型推导。

它用于完美转发。基本上,这意味着模板参数T&&的{​​{1}}是“通用参考”。

在您的情况下,由于T确实是左值,i被推断为TT。将int&应用于该值将被忽略(它将应用于引用本身,而不是引用的类型),因此从模板实例化的函数看起来像这样:

const

由于函数为int& get_or_default(int& t) const { return data; } const也被视为data,因此无法绑定到非const引用。