如何知道类型是否是 std::vector 的特化?

问题描述 投票:0回答:5
我整个早上都在解决这个问题,但没有任何结果。 基本上,我需要一个简单的元编程,如果传递的参数是一种

std::vector

 或不是的话,它允许我分支到不同的专业化。

某种

is_base_of

 用于模板。

有这样的事吗?

c++ templates metaprogramming template-specialization
5个回答
40
投票
在 C++11 中,你还可以用更通用的方式来实现:

#include <type_traits> #include <iostream> #include <vector> #include <list> template<typename Test, template<typename...> class Ref> struct is_specialization : std::false_type {}; template<template<typename...> class Ref, typename... Args> struct is_specialization<Ref<Args...>, Ref>: std::true_type {}; int main() { typedef std::vector<int> vec; typedef int not_vec; std::cout << is_specialization<vec, std::vector>::value << is_specialization<not_vec, std::vector>::value; typedef std::list<int> lst; typedef int not_lst; std::cout << is_specialization<lst, std::list>::value << is_specialization<not_lst, std::list>::value; }
    

28
投票
如果您需要一个特征类,这非常简单,您只需要一个通用模板和对任何

std::vector

的专业化:

#include <type_traits> #include <iostream> #include <vector> template<typename> struct is_std_vector : std::false_type {}; template<typename T, typename A> struct is_std_vector<std::vector<T,A>> : std::true_type {}; int main() { typedef std::vector<int> vec; typedef int not_vec; std::cout << is_std_vector<vec>::value << is_std_vector<not_vec>::value; }
    

4
投票
不,但您可以使用仅接受

std::vector<T>

 的模板函数进行重载。在这种情况下,编译器将选择最专业的模板。


2
投票
定义以下两个函数应该可行:

template<class T> bool is_vector(const std::vector<T>& x) {return true;} template<class T> bool is_vector(const T& x) {return false;}
示例:

auto x {std::vector<double> {23, 32, 33}}; auto y {1.2}; std::cout << is_vector(x) << std::endl; std::cout << is_vector(y) << std::endl;
    

0
投票
我最近遇到了几乎相同的问题,我需要弄清楚某物是否是另一种,例如,

std::vector<std::vector<float>>

是否是
std::vector<WHATEVER>
的一种。所以我实现了一个通用的
is_fuzzy_type_match_v
来检查它们,通过使用这个
consteval
函数,你可以在任何类型的模板中完成它,甚至是可变参数模板。

这里是代码:

#include <type_traits> namespace noaland { struct i_dont_care {}; template<typename T> struct is_i_dont_care : std::false_type {}; template<> struct is_i_dont_care<i_dont_care> : std::true_type {}; // if two type are not the same template<typename X, typename Y> struct is_fuzzy_type_matched { consteval auto operator()() { if constexpr (noaland::is_i_dont_care<X>::value || noaland::is_i_dont_care<Y>::value || std::is_same_v<X, Y>) { return std::true_type{}; } else { return std::false_type{}; } } }; template<typename X, typename Y> inline constexpr auto is_fuzzy_type_matched_v = decltype(is_fuzzy_type_matched<X, Y>()())::value; template<bool... R> consteval bool conjunction() { return (R && ...); } template<template<typename...> typename X, template<typename...> typename Y, typename... SUB_X, typename... SUB_Y> struct is_fuzzy_type_matched<X<SUB_X...>, Y<SUB_Y...>> { consteval auto operator()() { if constexpr (!conjunction<is_fuzzy_type_matched_v<SUB_X, SUB_Y>...>()) { return std::false_type{}; } else { return std::true_type{}; } } }; }
您可以像这样使用此功能:

int main() { static_assert(noaland::is_fuzzy_type_matched_v<std::vector<std::vector<std::vector<int>>>, std::vector<noaland::i_dont_care>>); return 0; }
由于我使用的是 C++20 功能 

consteval

,因此您需要添加 
--std=c++20
,或者您可以将 
consteval
 更改为 
constexpr

© www.soinside.com 2019 - 2024. All rights reserved.