为什么两种类型的std::is_same会给出不同的结果?

9
在下面的代码中,为什么调用fun的两种方式:fun(num)fun<const int>(num)在编译时会产生不同的结果?
#include <iostream>
using namespace std;

template<typename T, typename = typename enable_if<!std::is_same<int, T>::value>::type>
void fun(T val)
{
    cout << val << endl;
}

int main(void)
{
    const int num = 42;
    fun(num);  //ERROR!

    fun<const int>(num);  //Right

    return 0;
}

2
一个 int 的 prvalue 永远不会被声明为 const。 - curiousguy
1个回答

20
参数声明为按值传递; 然后在模板参数推导中,参数的顶层const限定符将被忽略。
在推导开始之前,对P和A进行以下调整:
1)如果P不是引用类型,
a) ...
b) ...
c) 否则,如果A是cv限定类型,则对于推导,顶层cv限定符将被忽略。
因此,对于给定的fun(num),模板参数T将被推断为int,而不是const int。
如果将参数更改为按引用传递,则const部分将被保留。例如:
template<typename T, typename = typename enable_if<!std::is_same<int, T>::value>::type>
void fun(T& val)

那么对于 fun(num)T 将被推断为 const int

2
此外,num 的类型是 const int,而 num 的值的类型只是 int。并不存在类型为 const int 的值(在技术上称为 prvalue)。 - curiousguy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接