首页 > 解决方案 > 当参数类型不属于一组类型时阻塞函数

问题描述

在特定要求中,我需要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

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

标签: c++c++17sfinaetypetraits

解决方案


你可以isCompatible这样写:

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

您无能为力,CompatibleTypeCheck因为您需要在某处指定所有允许的类型。

这是一个演示


请注意,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

这是一个演示


推荐阅读