禁用默认模板并仅通过 sfinae 使用专业化 [英] Disable default template and only use specialization through sfinae
问题描述
考虑以下系统:
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";
}
包装器的目的是让它衰减到它被模板化的类型(它是一个围绕该类型缓冲区的包装器).此外,我有一组函数是模板的模板化专业化.这是为了避免仅基于返回类型进行重载时的常见错误.
The purpose of the wrapper is to allow it to decay to the type it is templated to (it is a wrapper around a buffer of the type). Moreover, i have a set of functions that are templated specializations of a template. This is to circumvent the usual error when overloading based on only the return type.
但这不起作用,如下所述:
This doesn't work though, as noted here:
// the following should work, but doesn't because it's instantiating
// the func<ret, wrapper<float>> which doesn't exist resulting in a linker error
// instead of selecting the int func(float *) overload
wrapper<float> w;
func<int>(w);
相反,我希望这会产生编译时错误(但同样,它会产生链接时错误):
Conversely, i would like this to generate a compile-time error (but again, it's generating a link-time error):
// the following should generate a compile-time error
// since no explicit overload for int func(int *) exists
wrapper<int> w2;
func<int>(w2);
所以理想情况下,我想禁用原始模板(如果可能的话,可以通过 sfinae?),这样重载决议只考虑显式特化,如果找不到匹配项,则会生成编译时错误.可以这样做吗?
So ideally, i would like to disable the original template (maybe through sfinae if this is possible?) such that the overload resolution only considers the explicit specializations, and generates a compile-time error if no match is found. Can this be done?
clang 和 msvc 之间的便携式解决方案是必须的,但我使用的是两者的最新版本.
A portable solution between clang and msvc is a must, but I'm using the newest versions of both.
推荐答案
另一种方法可能是使用 static_assert:
Another approach may be to use static_assert:
template<typename Ret, typename T>
Ret func(T) {
static_assert(false, "template specialization required");
}
这篇关于禁用默认模板并仅通过 sfinae 使用专业化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!