当参数类型不属于一组类型时,阻塞一个函数

问题描述

在特定的要求中,我只需要为一组特定的允许类型实例化模板函数func

因此,我尝试使用已经可用的std::type_traits,然后使用std::enable_if来阻止实例化。这是我的实现。

// C++17
#include <vector>
#include <cstdint>
#include <iostream>
#include <type_traits>

using my_int_t      = std::int16_t;         // T1
using my_string_t   = std::string;          // T2
using my_vec_t      = std::vector<int>;     // T3
// and so on .. a long list of types 


/* Check input Type T : if it belongs to {T1,T2,T3} 
If it belongs then only allow this version of func to instantiate
*/
template<typename T,typename T1,typename T2,typename T3>
using isCompatible = std::bool_constant<std::is_same_v<T,T1>
                            || std::is_same_v<T,T2>
                            || std::is_same_v<T,T3> >;

template<typename T>
using CompatibleTypeCheck = std::enable_if_t< isCompatible<std::remove_reference_t<T>,my_int_t,my_string_t,my_vec_t>::value >;



template<typename T,typename = CompatibleTypeCheck<T>>
void func(T&& val) {
    std::cout <<"Hello from Generic Func" << std::endl;
}


int main() {

    // int z = 10;   
    // func(z); // Error ! as expected

    my_int_t w = 100;
    func(w); // OK
}

但是问题是允许的类型太多。是否有更好的方法来清除两个别名模板?即isCompatibleCompatibleTypeCheck

如果有更好的“惯用”方式来达到相同的结果,请提出建议。

解决方法

您可以这样写isCompatible

template<typename T,typename ...Ts> 
using isCompatible = std::bool_constant<(std::is_same_v<T,Ts> || ...)>;

CompatibleTypeCheck不能做太多事情,因为您需要在某处指定所有允许的类型。

这里是demo


请注意,enable_if通常在您要启用或禁用特定的重载时使用。在您的情况下,更简单的方法是将static_assert放在函数定义内:

template<typename T>
void func(T&& val) {
    static_assert(isCompatible<std::remove_reference_t<T>,my_int_t,my_string_t,my_vec_t>::value);
    std::cout <<"Hello from Generic Func" << std::endl;
}

这完全避免了使用CompatibleTypeCheck

这里是demo

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...