禁用默认模板并仅通过 sfinae 使用专业化 [英] Disable default template and only use specialization through sfinae

查看:85
本文介绍了禁用默认模板并仅通过 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆