Tak*_*ndo 5 c++ type-traits c++17
我编写了类型检查 constexpr 函数。如果类型为type1ortype2则返回 true,否则返回 false。
这是代码。它按我的预期工作。
#include <type_traits>
struct type1{};
struct type2{};
struct type3{};
template <typename T>
constexpr bool is_type1or2() {
return std::is_same_v<T, type1> || std::is_same_v<T, type2>;
}
static_assert(is_type1or2<type1>());
static_assert(is_type1or2<type2>());
static_assert(!is_type1or2<type3>());
int main(){}
Run Code Online (Sandbox Code Playgroud)
https://godbolt.org/z/dncKo1Pbb
现在,type1更改为具有非类型参数的模板。如何进行同类型检查?
#include <type_traits>
template <std::size_t N>
struct type1{};
struct type2{};
struct type3{};
template <typename T>
constexpr bool is_type1or2() {
return std::is_same_v<T, type2>;
}
template <typename T, std::size_t N>
constexpr bool is_type1or2() {
return std::is_same_v<T, type1<N>>;
}
// I want to write as follows but I couldn't find a way, so far.
// static_assert(is_type1or2<type1<42>>());
// so I pass explicit second template argument 42.
static_assert(is_type1or2<type1<42>, 42>());
static_assert(is_type1or2<type2>());
static_assert(!is_type1or2<type3>());
int main(){}
Run Code Online (Sandbox Code Playgroud)
https://godbolt.org/z/G1o5447z8
我尝试过,但无法消除第二个模板参数。它避免了通用代码。有什么好的方法来检查类型是type1<anyN>ortype2吗?
在我的实际情况中,我有 20 个非模板类型(如 )type2和 20 个模板类型(如type1. 其中一半需要匹配。我想尽可能避免代码重复。
对于模板类型type1<N>,N并不重要。这两个模板都很type1重要。is_type1or2<type1<10>>()所以和的结果is_type1or2<type1<20>>()总是相同的。我不需要定义基于单独模板参数专业化的匹配。
如果您更改 的语法static_assert以接受类型作为函数参数,则可以轻松解决此问题,因为这将允许函数模板参数推导(请参阅Takatoshi Kondo的回答)。
然而,这也可以通过编写一个模板来检查类型是否是模板的实例化来解决:
template<template <std::size_t> typename, typename>
struct is_instance_of : std::false_type {};
template<template <std::size_t> typename T, std::size_t N>
struct is_instance_of<T, T<N>> : std::true_type {};
Run Code Online (Sandbox Code Playgroud)
现在is_instance_of可以在函数中使用(不带参数推导):
template <typename T>
constexpr bool is_type1or2() {
return
is_instance_of<type1, T>::value // repeat for other templates that take a size_t parameter
or std::is_same_v<T, type2>; // repeat for non-template types
}
Run Code Online (Sandbox Code Playgroud)
如果您希望允许使用其他模板类型(即采用除 a 之外的参数的模板size_t),您可以is_instance_of根据需要进行编辑。
这是一个演示。