C++ 为什么GCC会编译带有value、rvalue和lvalue参数的重载函数?

C++ 为什么GCC会编译带有value、rvalue和lvalue参数的重载函数?,c++,C++,我不明白为什么这段代码会编译: #include <iostream> class T { }; void fun(T) { std::cout << __PRETTY_FUNCTION__ << std::endl; } void fun(const T&) { // Why does this compile? std::cout << __PRETTY_FUNCTION__ << std::endl

我不明白为什么这段代码会编译:

#include <iostream>

class T {
};


void fun(T) {
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}

void fun(const T&) { // Why does this compile?
    std::cout << __PRETTY_FUNCTION__ << std::endl;
}

void fun(const T&&) { // Why does this compile?

}


int main() {
    return 0;
}
重载T和const T&总是冲突的,所以我不明白GCC为什么编译它。 我已经读到,像category value的参数一样,不能被右值或左值的参数重载

如果T和const T&&的重载有效,是否意味着不可能以任何方式将右值传递给此函数,因为任何调用都是不明确的?或者这是一种消除通话歧义的方法

GCC版本:GCC版本7.3.0 Ubuntu 7.3.0-27ubuntu1~18.04
__cpluplus=201103

在普通重载解析下,重载确实是冲突的、不明确的,但它们仍然可以通过显式方式解析

T a;
static_cast<void(*)(T)>(fun)(a);         // calls `T` version
static_cast<void(*)(const T &)>(fun)(a); // calls `const T &` version

例如,请参见它是如何完成的。

我假设您已经在这个代码段之前的某个地方定义了类型T。当然,否则代码将无法编译

如果一个重载取T,一个重载取const,那么重载解析永远不能选择其中一个而不是另一个,这是不完全正确的。例如,如果参数的类型为volatile T,则必须选择重载take T而不是take const T&。但是,撇开这种情况不谈,这些函数始终可以通过完全绕过重载解析来单独调用:

static_cast<void(*)(T)>(fun)(x);  // calls void fun(T) on x

编译器的工作不是阻止您声明导致重载解决问题的函数。一个好的编译器也许会提醒你;但是,我认为这样的警告是没有必要的,因为几乎没有程序员会写这样的代码,除了作为一个实验。

const t&&几乎从来都不是你想要的。删除常量并重新编译。您发布的代码不是用g++为我编译的。它不是GCC版本-它只是不可编译的代码。我的g++版本编译它,但调用此函数不会编译。问题是关于函数实现本身,特别是,category value的参数不能被category rvalue或lvalueOk的参数重载,我明白了。非常感谢。因此,具有非引用参数的函数可以通过静态_cast解决歧义,通过l值或r值引用重载
static_cast<void(*)(T)>(fun)(x);  // calls void fun(T) on x