特化可变参数模板成员函数
Specialize variadic template member function
有没有办法让这个 "fake overloading" 参数专业化起作用?
#include <iostream>
class Foo
{
public:
template < typename T, typename ... Args >
T* bar (Args&& ... args);
};
template <>
int* Foo::bar()
{
std::cout << "int* bar()\n";
return new int;
}
// error: template-id ‘bar<>’ for ‘double* Foo::bar(double)’ does not match any template declaration
template <>
double* Foo::bar(double d)
{
std::cout << "double* bar(" << d << ")\n";
return new double;
}
int main()
{
Foo f;
f.bar<int>();
f.bar<double>(3.0);
}
一个解决方案是实际重载函数,例如
class Foo
{
public:
template < typename T, typename ... Args >
T* bar (Args&& ... args);
template < typename T, typename U >
T* bar (U u);
};
但我希望尽可能避免这种情况。我正在查看 return 类型和参数的数十种允许组合,因此重载是不切实际的。
我假设一些 SFINAE 魔术应该可以只启用非常特定的 return 类型和参数组合,但我觉得我可能缺少一个更简单的选项。
如错误消息所述,专业化 double
的参数类型与主模板 Args&&
的参数类型不匹配。
主模板正在应用转发引用,它可以实例化为左值引用或右值引用。对于右值引用(与 main()
中的用法相匹配),特化应该是
template <>
double* Foo::bar(double&& d)
{
std::cout << "double* bar(" << d << ")\n";
return new double;
}
有没有办法让这个 "fake overloading" 参数专业化起作用?
#include <iostream>
class Foo
{
public:
template < typename T, typename ... Args >
T* bar (Args&& ... args);
};
template <>
int* Foo::bar()
{
std::cout << "int* bar()\n";
return new int;
}
// error: template-id ‘bar<>’ for ‘double* Foo::bar(double)’ does not match any template declaration
template <>
double* Foo::bar(double d)
{
std::cout << "double* bar(" << d << ")\n";
return new double;
}
int main()
{
Foo f;
f.bar<int>();
f.bar<double>(3.0);
}
一个解决方案是实际重载函数,例如
class Foo
{
public:
template < typename T, typename ... Args >
T* bar (Args&& ... args);
template < typename T, typename U >
T* bar (U u);
};
但我希望尽可能避免这种情况。我正在查看 return 类型和参数的数十种允许组合,因此重载是不切实际的。
我假设一些 SFINAE 魔术应该可以只启用非常特定的 return 类型和参数组合,但我觉得我可能缺少一个更简单的选项。
如错误消息所述,专业化 double
的参数类型与主模板 Args&&
的参数类型不匹配。
主模板正在应用转发引用,它可以实例化为左值引用或右值引用。对于右值引用(与 main()
中的用法相匹配),特化应该是
template <>
double* Foo::bar(double&& d)
{
std::cout << "double* bar(" << d << ")\n";
return new double;
}