当参数类型不属于一组类型时阻止函数
block a function when argument type does not belong to a set of types
在特定要求中,我需要允许实例化模板函数 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
}
但问题是允许的类型太多了。有没有更好的方法来清理这两个别名模板?即 isCompatible
和 CompatibleTypeCheck
.
如果有任何更好的“惯用”方法可以达到相同的结果,请提出建议。
你可以这样写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。
在特定要求中,我需要允许实例化模板函数 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
}
但问题是允许的类型太多了。有没有更好的方法来清理这两个别名模板?即 isCompatible
和 CompatibleTypeCheck
.
如果有任何更好的“惯用”方法可以达到相同的结果,请提出建议。
你可以这样写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。