C ++ - 在具有非类型模板参数的模板类上专门化函数模板

Posted

技术标签:

【中文标题】C ++ - 在具有非类型模板参数的模板类上专门化函数模板【英文标题】:C++ - specialize function template on a templated class with a non type template parameter 【发布时间】:2017-11-25 15:01:34 【问题描述】:

我有一个类模板 Foo:

template <class A, A value, class B>
class Foo ;

我有一个函数模板 validateType()

template <class T>
bool validateType() 
    return false;

现在我想将它专门用于某些类型,包括 Foo,以便该函数在编译时执行一些 static_asserts。我试过这个:

template <class A, class B, Foo<A, A val, B>>
bool validateType() 
    // do some static asserts

还有这个:

template <class A, A val, class B>
bool validateType<Foo<A, val, B>>() 
    // do some static asserts

在第一个中,编译器说:

error: wrong number of template arguments (2, should be 3)
 template <class A, class B, Foo<A, A val, B>>
                                            ^~
note: provided for ‘template<class A, A value, class B> class Foo’
 class Foo ;
       ^~~
error: two or more data types in declaration of ‘validateType’
 bool validateType() 
                   ^
error: expected ‘>’ before ‘’ token
 bool validateType() 
                     ^

在第二种情况下,我得到了

error: non-class, non-variable partial specialization ‘validateType<Foo<A, val, B> >’ is not allowed
 bool validateType<Foo<A, val, B>>() 
                                   ^

这应该怎么做?

【问题讨论】:

【参考方案1】:

函数模板不允许部分模板特化。 使用 SFINAE 或 类模板

template <class T>
struct validateType : std::false_type ;

template <class A, A val, class B>
struct validateType<Foo<A, val, B>> : std::true_type ;

编辑:

这应该也适用于模板函数吗?

没有。 函数模板不允许部分模板特化。

对于模板函数,使用 SFINAE。

例如,这个示例检查天气 T 是无符号整数类型(C++17)。

template<typename T, std::enable_if_t<std::is_unsigned_v<T>, std::nullptr_t> = nullptr>
T foo(T n);
std::is_unsigned_v 在 C++17 中添加。在 C++17 之前,使用 std::is_unsigned&lt;T&gt;::value.https://en.cppreference.com/w/cpp/types/is_unsigned std::enable_if_t 在 C++14 中添加。在 C++14 之前,使用 typename std::enable_if&lt;con, T&gt;::type.https://en.cppreference.com/w/cpp/types/enable_if std::nullptr_t 只能挖一个值(nullptr),以便我将其用于 SFINAE 启用程序。 (ja)https://qiita.com/kazatsuyu/items/203584ef4cb8b9e52462

但是,在您的情况下,您应该使用类模板。使用类模板来检查 T 是否是模板类 foo 是最简单的方法(顺便说一句,不适用于模板类 foo,std::is_same 是最简单的方法)。

【讨论】:

这应该也适用于模板函数吗?

以上是关于C ++ - 在具有非类型模板参数的模板类上专门化函数模板的主要内容,如果未能解决你的问题,请参考以下文章

C++20:非类型模板参数中的非捕获 lambda

C++模板进阶

[C/C++]详解C++中的模板

[C/C++]详解C++中的模板

C++11 中的非类型可变参数函数模板

C++17和C++11中的非类型模板参数有啥区别?