我有一个模板 class A
template <unsigned int m>
class A
{
public:
A(int) {}
};
Run Code Online (Sandbox Code Playgroud)
哪个有构造函数int.我有一个手术:
template<unsigned int m>
A<m> operator+(const A<m>&, const A<m>&)
{
return A<m>(0);
}
Run Code Online (Sandbox Code Playgroud)
但是当我打电话时:
A<3> a(4);
A<3> b = a + 5;
A<3> c = 5 + a;
Run Code Online (Sandbox Code Playgroud)
我想int隐式转换为A,但编译器会抛出错误.
有没有优雅的方法来启用隐式转换而不使用以下解决方案:
a + A<m>(5)operator+<3>(a, 5)在下面的示例中,0它以一种特殊的方式运行:它选择与示例函数调用所期望的不同的重载。我想知道为什么。我的理解也如下。
#include <iostream>
template<typename T>
void f(T a) {
std::cout << "first" << std::endl;
}
template<typename T>
void f(T* a) {
std::cout << "second" << std::endl;
}
int main()
{
f(0);
f<size_t>(0);
f<size_t>(0UL);
f(1);
f<size_t>(1);
}
Run Code Online (Sandbox Code Playgroud)
输出:
first
second
first
first
first
Run Code Online (Sandbox Code Playgroud)
我的理解:
f(0)- 模板参数推导,整数文字0是int类型,因此f选择第一个T=int
f<size_t>(0)-带有整数提升的显式模板实例化,选择的类型是T=size_t,选择第一个函数并从到提升0(我在这里错了)intsize_t
f<size_t>(0UL)- 与上面相同,但没有升级(0 已经是 type size_t)
f(1)- 与 …
c++ templates function-templates overload-resolution template-argument-deduction
下面是一个典型的 C 函数,它采用经典函数指针作为参数:
int DoThingy( const char* stuff, int(*helper)(int))
{
int result = 0;
//...call helper...
return result;
}
Run Code Online (Sandbox Code Playgroud)
下面我用一个非捕获 lambda 来调用上面的内容,它神奇地“降级”为函数指针。在“A”处,转换是隐式的。在“B”处,它是明确的。都好。
void UseThingy()
{
auto lam = [](int)->int {
return 42;
};
int i;
i = DoThingy( "hello", lam); //"A" works
int (*ptr)(int) = lam;
i = DoThingy( "hello", ptr); //"B" works
}
Run Code Online (Sandbox Code Playgroud)
但在这个新示例中,回调函数的签名取决于模板类型:
template <typename T>
int DoThingy2( const char* stuff, int (*helper)(T))
{
int result = 0;
//...call helper...
return result;
}
Run Code Online (Sandbox Code Playgroud)
当我尝试使用上面的这个版本时,“C”行甚至无法编译。然而“D”处的显式版本是有效的。什么?为什么这些不一样?请注意,当我在“E”处给出显式模板参数时,它可以工作,但当然可以<int>从 的签名推断出来lam …