如何在模板函数中实现模板类类型



我想为STL容器设计一个打印函数,包括:std::vector, std::map, std::unodered_map, std::set, std::unordered_set, std::list。。。。

理想的功能看起来像:

template<typename T>
void Show(const T& t)
{
if (istype(t, std::vector)) 
{  
// here is a presudo code
// print vector
for (auto i: t) cout << i << endl;
} 
else if (istype(t, std::unordered_map)) 
{
// print unordered_map
} 
else 
{  }
}

我认为问题发生在istype()

我知道有一些像std::is_same这样的函数可以做到这一点。

但它似乎只能在intfloat上操作,不能在std::vector上操作,你能帮上忙吗?

但它似乎只能在intfloat上操作,无法操作在std::vector上,你能帮忙吗?

对于像搁浅容器这样的模板类,您需要指定模板参数来获得具体类型,然后可以使用std::is_same进行比较。这意味着像std::is_same_v<T, std::vector<int>>std::is_same_v<T, std::vector<float>>这样的东西会起作用。

另一方面,您需要查看传递的容器是否是标准容器的专用容器。在那里,你需要自己的std::is_same_v型特征。

一种可能的实现方式如下所示。还要注意,您需要使用if constexpr(由于c++17(而不是普通的if来进行编译时分支。如果无法访问c++17,则需要使用SFINAE。

(见演示(

#include <iostream>
#include <type_traits> // std::false_type, std::true_type
#include <vector>
#include <list>
#include <string>
#include <map>
template<typename Type, template<typename...> class Args>
struct is_specialization final : std::false_type {};
template<template<typename...> class Type, typename... Args>
struct is_specialization<Type<Args...>, Type> : std::true_type {};

template<typename ContainerType>
constexpr void show(const ContainerType& container) noexcept
{
if constexpr (is_specialization<ContainerType, std::vector>::value
|| is_specialization<ContainerType, std::list>::value)
{  
for (const auto ele : container)
std::cout << ele << 't';
std::cout << 'n';
}
else if constexpr (is_specialization<ContainerType, std::map>::value)
{
for (const auto& [key, value]: container)
std::cout << key << " " << value << 't';
std::cout << 'n';
}
// ... so on!
}
int main()
{
std::vector<int> vec{ 1, 2, 3 };
show(vec);
std::list<int> list{ 11, 22, 33 };
show(list);
std::map<int, std::string> mp{ {1, "string1"}, {2, "string2"}, {3, "string3"} };
show(mp);
}

所有STL容器的共同特点是它们可以在[begin(),end())范围内迭代。对于序列容器,必须将T打印为value_type;对于(无序(关联容器,必须处理将std::pair<const Key, T>打印为valuetype。仅此而已。我看不出有任何理由在您的实现中检查传递的容器的类型。

template<class T>
void Print(const T& val) {
std::cout << val;
}
template<class Key, class Value>
void Print(const std::pair<const Key,Value>& p) {
Print(p.first);
std::cout << " - ";
Print(p.second);
}
template<class Cont>
void PrintCont(const Cont& cont) {
std::cout << std::endl;
for (auto it = cont.begin(); it != cont.end(); ++it) {
Print(*it);
std::cout << " ";
}
std::cout << std::endl;
}
std::array<int,2> a{1,2};
std::vector<int> v{1,2,3};
std::list<double> l{2., 3., 5.4};
std::map<int,double> m{ {1,2.},{10,3.14} };
std::multimap<int,int> m2{ {2,3},{4,5} };
std::set<float> s{1.f, 23.f, 2.f};
std::unordered_map<int,Foo> m3{ {1,Foo(1)}, {2,Foo(2)}, {3,Foo(3)}}; 
PrintCont(a);
PrintCont(v);
PrintCont(l);
PrintCont(m);
PrintCont(a);
PrintCont(s);
PrintCont(m2);
PrintCont(m3);

现场演示

相关内容

  • 没有找到相关文章

最新更新