如何自定义模板以不包含某些类型[重复]

Posted

技术标签:

【中文标题】如何自定义模板以不包含某些类型[重复]【英文标题】:How to customize template to not include certain types [duplicate] 【发布时间】:2019-12-03 17:05:26 【问题描述】:

在Template class type-specific functions 之后,如何自定义我的模板代码以不针对某些类型进行编译? 如果问题不清楚,请查看此示例。

///** template class ***/
template<typename T>
class testClass
testClass();
T parameter;

template<typename T>
void testClass<T>::print()cout<<parameter.value<<endl;

上面的类应该适用于以下类型:

 //** types file **/
    class paramtype1
    int value;
    
    class paramtype2
    int value;
    
    class paramtype3
    

如您所见,paramtype3 没有value,所以我收到一个编译错误,指出未定义value。我知道如果我想为某种类型专门化一个模板类函数,我需要这样做:

template<>
void testClass<paramtype1>::print()cout<<parameter.value<<endl;

但是,有什么办法可以反其道而行之,只排除某些特定类型吗?

【问题讨论】:

您应该编辑您的问题以包含具体您想要包含/排除的类型,以及为什么。如果您只想在类型具有特定成员时启用特化,您将使用不同的技术。 另外,当您尝试将模板与 paramtype3... 一起使用时遇到编译器错误,这并不意味着它已经没有针对该类型进行编译? 【参考方案1】:

如果要启用/禁用完整的类/结构,可以使用 SFINAE 和部分专业化。

以下是一个 C++17 示例

template <typename T, typename = void>
struct testClass;

template <typename T>
struct testClass<T, std::void_t<decltype(T::value)>>
 
   testClass()
     ;

   T parameter;

   void print()
     std::cout << parameter.value << std::endl; 
 ;

如果您只想启用/禁用print() 功能,则必须对其进行模板化;举例

template <typename U = T>
std::void_t<decltype(U::value)> print()
  std::cout << parameter.value << std::endl; 

也可以

template <typename U = T>
std::void_t<decltype(U::value), std::enable_if_t<std::is_same_v<U, T>>> 
    print()
  std::cout << parameter.value << std::endl; 

如果你想确保没有人可以“劫持”解释模板类型调用的方法

testClass<paramtype3>.print<paramtype1>():

【讨论】:

【参考方案2】:

我个人会做的是排除使用某些类型的权限:

template <class T, class... Ts>
struct is_any : std::disjunction<std::is_same<T, Ts>...> ;

// https://***.com/questions/17032310/how-to-make-a-variadic-is-same

template <typename T>
void do_something() 
    static_assert(!is_any<T, int, bool>::value, "do_something<T> cannot be used with T as int or bool");
    // code here

允许您添加自定义断言消息,以便轻松发现问题所在。

【讨论】:

以上是关于如何自定义模板以不包含某些类型[重复]的主要内容,如果未能解决你的问题,请参考以下文章

当自定义模板已应用于节点的内容类型时,如何在 Drupal 6 中自定义特定节点?

自定义项目类型模板

如何从模板中的自定义帖子类型中仅提取一个类别?

使用 Yeoman 自定义 Generator,包含新建 Vue 模板案例

Django - 如何在任何包含的模板中使用我的自定义过滤器?

模板继承 组件 自定义过滤器 静态文件 别名 反向解析