模板类型不是使用指针类型推断的

Jon*_*ter 2 c++ templates

我惊讶地发现T在以下代码中无法成功推断:

template <typename T>
void Set(T* a,T b)
{
    *a = b;
}

void Test()
{
    unsigned long a;
    Set(&a, 1);
}
Run Code Online (Sandbox Code Playgroud)

VC++抱怨模棱两可:

1>test.cpp(10): error C2782: 'void Set(T *,T)' : template parameter 'T' is ambiguous
1>          test.cpp(32) : see declaration of 'Set'
1>          could be 'int'
1>          or       'unsigned long'
Run Code Online (Sandbox Code Playgroud)

显然这可以通过改变呼叫来解决,Set(&a, 1ul);但我的问题是为什么这是必要的?

为什么不能T使用指针的类型推导出来,哪个应该是明确的?

有没有办法重写模板,以便原始调用Set成功编译?

Col*_*mbo 6

为什么不能使用指针的类型推导出T,这应该是明确的?

因为你没有告诉编译器这样做.模板参数的扣除不一致会导致扣减失败.

有没有办法重写模板,以便原始调用Set将成功编译?

是的,使用非推断的上下文.

template <typename T>
struct identity {using type=T;};
template <typename T>
using identity_t = typename identity<T>::type;

template <typename T>
void Set(T* a, identity_t<T> b) {
    *a = b;
}
Run Code Online (Sandbox Code Playgroud)

演示.
或者使用第二个模板参数.