在编译时间检查模板参数类型是否设置或多键,并且容器的元素类型是算术的
Check at compile time if a template argument type is set or multiset, and element type of the container is arithmetic
i具有一个名为'quare'接受2个参数的函数,每个函数应为std :: set ::或std :: multiSet,并且容器的元素类型应为算术类型(int,float,double ...)。如果不满足2个条件,我希望编译器报告错误。
我希望我的代码可以这样运行:
int main(void)
{
std::set<int> s1;
std::set<int> s2;
equal(s1, s2); // OK
std::multiset<float> s3;
std::multiset<float> s4;
equal(s3, s4); // OK
std::set<int> s5;
std::multiset<int> s6;
equal(s5, s6); // compile error
std::set<int*> s7;
std::set<int*> s8;
equal(s7, s8); // compile error
std::vector<int> s9;
std::vector<int> s10;
equal(s9, s10); // compile error
return 0;
}
现在可以检查元素是否为算术类型,如下:
template <class Container, class = typename std::enable_if<std::is_arithmetic<typename Container::value_type>::value>::type>
bool equal(const Container &container1, const Container &container2)
{
return true;
}
但是如何确保仅设置容器或多键?
编译器可以支持C 11,例如VC2015或GCC4.8
创建一个is_set_or_multiset
类型特征,该特质将使用模板专业匹配std::set<...>
和std::multiset<...>
:
template <typename>
struct is_set_or_multiset : std::false_type {};
template <typename... Ts>
struct is_set_or_multiset<std::set<Ts...>> : std::true_type {};
template <typename... Ts>
struct is_set_or_multiset<std::multiset<Ts...>> : std::true_type {};
然后将其用作enable_if
子句中的附加条件:
template <class Container,
class = typename std::enable_if<
std::is_arithmetic<typename Container::value_type>::value
&& is_set_or_multiset<Container>{}
>::type>
bool equal(const Container &container1, const Container &container2)
{
return true;
}
wandbox上的实时示例
template<template<class...>class Z, class T>
struct is_instance_of_template : std::false_type {};
template<template<class...>class Z, class...Ts>
struct is_instance_of_template<Z,Z<Ts...>> : std::true_type {};
template<class Container>
using value_type_t = typename Container::value_type;
template <class Container,
std::enable_if_t<
std::is_arithmetic<value_type_t<Container>>{}
&& (
is_instance_of_template<std::set, Container>{}
|| is_instance_of_template<std::multiset, Container>{}
)
>* =nullptr
>
bool equal(const Container &container1, const Container &container2)
{
static_assert( std::is_arithmetic<value_type_t<Container>>{},
"Container must contain arithmetic values"
);
static_assert(
is_instance_of_template< std::set, Container >{}
|| is_instance_of_template< std::multiset, Container >{},
"Container must be a set or multiset"
);
return true;
}
static_assert
S只是为了验证其上方的Sfinae。如果您不需要Sfinae,则可以跳过Sfinae - 如果您可以使用硬构建休息而不是无法匹配此过载。
请注意,根据我的经验,enable_if_t<>* =nullptr
技术在某些编译器(例如MSVC2015)上无法完美地工作。在这些编译器上,使用class=enable_if_t<>
。我使用enable_if_t<>* =nullptr
,因为它摆脱了"相同的模板签名"问题。
相关文章:
- 在C++中,如何通过几种类型从元组中选择多个元素
- 如何为 c++ 的不同变量类型的结构元素创建动态数组?
- 在 C++ 中输出枚举类类型的向量元素
- C++默认情况下,指针类型数组的元素是否保证初始化为 nullptr?
- 如何使用模板根据类型将元素添加到各种容器中
- C++ 未初始化的本地(非全局)int 数组中的元素类型到底是什么?
- OpenCV C++:当垫子类型未知时无法访问垫子元素?
- C++如何乘以包含 std::variant 元素的向量的迭代器?正在执行迭代器类型的转换?
- C++:是否可以编写一个函数,将不同类型的元素附加到变体数组中?
- C++通过别名指针以静默方式将错误的类型分配给数组元素
- 我无法在用forward_as_tuple创建的元组中按类型访问元素
- 如何告诉自动推断向量<bool>元素的非引用类型
- 为什么将函数的返回类型从结构节点*更改为void后,链表的元素没有显示create_ll和显示?
- 如何为基类通用类型创建向量以使用具体类型元素
- 按索引将类类型元素从一个向量复制到另一个 c++
- 如何实现数据结构,就像C 中的数组一样支持不同的类型元素
- 如何在构造具有不同类型元素的向量副本时显式转换
- 处理特定类型元素的任何容器的非模板函数
- *类型元素容器的qt排序
- 如何将两个双数据类型元素转换为一个Point数据类型