为什么当T = int&?时构造函数Message(const T&data)与Message(T && data)冲突

问题描述 投票:3回答:1
template <typename T>
struct Message {
    T data;
    explicit Message(T&& data) : data(std::move(data)) {
        std::cout << "Move data" << std::endl;
    }

    explicit Message(const T& data) : data(data) {
        std::cout << "Copy data" << std::endl;
    }
};

template <typename T>
inline Message<T>*
makeMessage(T&& data) {
    return new Message<T>{std::forward<T>(data)};
}


int main() {
    const int a = 1024;
    auto *copy_msg = makeMessage(a);
}

[有一个具有两个构造函数的模板类MessageMessage(T&& data)Message(const T& data),当我调用makeMessage(a)时遇到了以下编译时错误。

错误:“消息”的多个重载实例化到相同的签名“ void(const int &&)”

显式消息(常量T&数据):数据(数据){

先前的声明在这里

显式消息(T &&数据):数据(std :: move(数据)){

但是,当我调用make_message(1024)make_message(std::move(a))时,它起作用。

那么为什么当T = int&时构造函数Message(const T& data)Message(T&& data)重复?

c++ c++11 compiler-errors move-semantics overload-resolution
1个回答
0
投票

那么为什么当T = int&时构造函数Message(const T&data)与Message(T && data)重复?

由于参考折叠规则。

没有引用作为参考。当T是左值引用时-假设int &,那么从语法上讲T &似乎是int & &。但是这种类型不存在。语言规则说,在这种情况下,T &会折叠为int &

类似地,没有const引用之类的东西(不要与const的引用混淆,人们在说const引用时有时指的是)。当T是左值引用时-假设int&,那么从语法上讲T const(与const T相同)似乎是int& const(不要与int const &混淆,后者与const int & ])。但是这种类型不存在。语言规则说,在这种情况下,T const会折叠为int &

C ++ 11引入了右值引用,这为我们带来了新的折叠规则。简而言之,“对右值引用的右值引用”折叠为右值引用,但是“对任何引用的左值引用”以及“对左值引用的任何引用”都折叠为左值引用。此规则是转发引用如何工作的法宝的一部分。

同样,给定T = int &,它们声明相同的功能:

explicit Message(T&& data)      // type of argument is int &
explicit Message(const T& data) // type of argument is int &

奖金:对于非引用也有崩溃的规则:没有const const type这样的东西。这样,给定const T,其中Tconst int,则它折叠为const intvolatile也一样。

© www.soinside.com 2019 - 2024. All rights reserved.