C++ 禁用默认模板并仅通过sfinae使用专门化
考虑以下系统:C++ 禁用默认模板并仅通过sfinae使用专门化,c++,templates,sfinae,overload-resolution,C++,Templates,Sfinae,Overload Resolution,考虑以下系统: template<typename T> struct wrapper { operator T * () { return nullptr; } }; template<typename Ret, typename T> Ret func(T); template<> int func(float * in) { std::cout << "lon
template<typename T>
struct wrapper
{
operator T * () { return nullptr; }
};
template<typename Ret, typename T>
Ret func(T);
template<>
int func(float * in)
{
std::cout << "long";
}
template<>
long func(float * in)
{
std::cout << "int";
}
模板
结构包装器
{
运算符T*(){return nullptr;}
};
模板
Ret func(T);
模板
int func(浮点*in)
{
std::cout如果你这样做
template<typename Ret> Ret func(float*);
template Ret func(float*);
它按预期工作:虽然Jarod的答案解决了其中一个问题,但我仍然需要一种方法来重载函数参数(在这种情况下会生成“无匹配模板”错误)-我可能没有在OP中说明这一点
我突然意识到,参数类型总是依赖于返回类型。然后我可以构造一个helper结构,它将执行sfinae:
template<typename T>
struct option_of;
template<>
struct option_of<int>
{
typedef float value;
};
template<>
struct option_of<long>
{
typedef double value;
};
模板
结构选项_;
模板
结构选项
{
typedef浮点值;
};
模板
结构选项
{
typedef双值;
};
然后默认模板将如下所示:
template<typename Ret>
Ret func(typename const option_of<Ret>::value *);
template<>
int func(const float * in)
{
std::cout << "long";
}
template<>
long func(const double * in)
{
std::cout << "int";
}
模板
Ret func(typename const option_of::value*);
然后重载可以这样构造:
template<typename Ret>
Ret func(typename const option_of<Ret>::value *);
template<>
int func(const float * in)
{
std::cout << "long";
}
template<>
long func(const double * in)
{
std::cout << "int";
}
模板
int func(常量浮点*in)
{
std::cout另一种方法可能是使用静态断言:
template<typename Ret, typename T>
Ret func(T) {
static_assert(false, "template specialization required");
}
模板
Ret func(T){
静态_断言(false,“需要模板专门化”);
}
你的问题并不像模板参数推导那样超载解决问题,它不考虑隐式转换。@ P0W,因为你不能超载这两种。唯一的区别是返回类型。@ TC AHH,我明白了,谢谢你的想法——它是解决方案的一部分(见我的答案)。在您的示例中,不仅参数依赖于返回类型,还依赖于其他方式。如果您创建了return\u of::value,那么您的模板参数可以是隐式的,并且您可以在不使用模板参数的情况下调用func(w2)。
template<typename Ret, typename T>
Ret func(T) {
static_assert(false, "template specialization required");
}