C++ 如何辨别地图由哪些类型组成
我想知道C++ 如何辨别地图由哪些类型组成,c++,c++11,C++,C++11,我想知道std::map中的类型是否由std::map本身组成。我的场景如下所示: template <typename Key, typename T, typename Compare = std::less<Key>, typename Allocator = std::allocator<std::pair<const Key, T>>> void mapPrint(std::map<Key, T, Compare
std::map
中的类型是否由std::map
本身组成。我的场景如下所示:
template <typename Key, typename T, typename Compare = std::less<Key>,
typename Allocator = std::allocator<std::pair<const Key, T>>>
void mapPrint(std::map<Key, T, Compare, Allocator> m) {
}
这项职能。是否可以递归地遍历所有类型,直到只找到普通类型
编辑:
这是我的节目:
#include <iostream>
#include <map>
class A {
public:
void testFunc(int) {}
};
class B {
public:
void testFunc(int) {}
};
class C {
public:
void notTestFunc() {}
};
template <typename T>
struct hasTestFunc {
typedef char (& yes)[1];
typedef char (& no)[2];
template <typename C> static yes comp(decltype(&C::testFunc));
template <typename> static no comp(...);
static bool const value = sizeof(comp<T>(nullptr)) == sizeof(yes);
};
template <typename Key, typename T, typename Compare = std::less<Key>,
typename Allocator = std::allocator<std::pair<const Key, T>>>
void mapPrint(std::map<Key, T, Compare, Allocator> m) {
std::cout << hasTestFunc<Key>::value << std::endl;
std::cout << hasTestFunc<T>::value << std::endl;
}
int main() {
std::map<std::map<A,A>, A> m;
mapPrint(m);
return 0;
}
#包括
#包括
甲级{
公众:
void testFunc(int){}
};
B类{
公众:
void testFunc(int){}
};
C类{
公众:
void notTestFunc(){}
};
模板
结构hasTestFunc{
typedef字符(&yes)[1];
typedef字符(&no)[2];
模板静态yes comp(decltype(&C::testFunc));
模板静态无组件(…);
静态布尔常量值=sizeof(comp(nullptr))==sizeof(yes);
};
模板
无效地图打印(标准::地图m){
std::cout您希望对函数mapPrint
进行部分专门化。但这是不可能的,因此我们需要退回到结构的部分专门化。(注意,为了方便起见,我将您的T
重命名为值
)
现在是一个简单的函数,它将在映射上递归
template<typename T>
void printHasTestFunc()
{
if constexpr (is_std_map<T>::value)
{
printHasTestFunc<typename T::key_type>();
printHasTestFunc<typename T::mapped_type>();
}
else
std::cout << hasTestFunc<T>::value << std::endl;
}
.对于一些重载,您可以执行以下操作:
template <typename> struct Tag {};
template <typename T>
void TagPrint(Tag<T>) {
std::cout << hasTestFunc<T>::value << std::endl;
}
template <typename Key, typename T, typename Compare, typename Allocator>
void TagPrint(Tag<std::map<Key, T, Compare, Allocator>>) {
TagPrint(Tag<Key>{});
TagPrint(Tag<T>{});
}
template <typename Key, typename T, typename Compare, typename Allocator>
void mapPrint(const std::map<Key, T, Compare, Allocator>&) {
return TagPrint(Tag<std::map<Key, T, Compare, Allocator>>{});
}
模板结构标记{};
模板
无效标记打印(标记){
std::cout回答被问到的问题:是的,这是可能的,使用专门化和一些辅助粘合代码。确切的细节取决于具体的细节,即,在这种情况下,预期的结果到底是什么?std::tuple
?哪个int
是哪个。或者,仅仅是一个int
和另一个int
?同样的问题。为了回答这样的问题,你必须:提供更多的细节,并展示你目前的工作。如果你不熟悉这些高级模板概念,如专业化,你需要先学习它们,否则你可能根本不理解答案。你需要进一步解释为什么你需要这样做“想要输出吗"也就是说,std::map
中有三个基本类型,三个非映射,三个A
s;还有两个std::map
s,所以如果所有内容都是递归检查的,那么输出应该包括三个0和两个1。很抱歉,我在帖子中犯了一个错误,我希望输出为:1,我只想检查该类型是否有member函数testFunc,如果类型不是容器。如果它是容器,我想检查容器所包含的类型是否具有成员函数testFunc。“容器”与“std::map”有很大不同,如示例所示。这对于地图来说应该很容易,但如果需要检查任意容器,则会变得更复杂。在stackoverflow.com上获得好答案的关键是能够提出一个简洁、准确的问题。如果你不能提出正确的问题,你不能指望任何人给你正确的答案。
template<typename T>
void printHasTestFunc()
{
detail::printerHasTestFunc<T>{}();
}
template <typename Key, typename Value, typename Compare = std::less<Key>,
typename Allocator = std::allocator<std::pair<const Key, Value>>>
void mapPrint(std::map<Key, Value, Compare, Allocator> m) {
printHasTestFunc<Key>();
printHasTestFunc<Value>();
}
template <typename>
struct is_std_map : std::false_type{};
template <typename Key, typename Value, typename Less, typename Compare>
struct is_std_map<std::map<Key, Value, Less, Compare>> : std::true_type{};
template<typename T>
void printHasTestFunc()
{
if constexpr (is_std_map<T>::value)
{
printHasTestFunc<typename T::key_type>();
printHasTestFunc<typename T::mapped_type>();
}
else
std::cout << hasTestFunc<T>::value << std::endl;
}
template <typename Key, typename Value, typename Compare = std::less<Key>,
typename Allocator = std::allocator<std::pair<const Key, Value>>>
void mapPrint(std::map<Key, Value, Compare, Allocator> m) {
printHasTestFunc<std::map<Key, Value, Compare, Allocator>>();
}
template <typename> struct Tag {};
template <typename T>
void TagPrint(Tag<T>) {
std::cout << hasTestFunc<T>::value << std::endl;
}
template <typename Key, typename T, typename Compare, typename Allocator>
void TagPrint(Tag<std::map<Key, T, Compare, Allocator>>) {
TagPrint(Tag<Key>{});
TagPrint(Tag<T>{});
}
template <typename Key, typename T, typename Compare, typename Allocator>
void mapPrint(const std::map<Key, T, Compare, Allocator>&) {
return TagPrint(Tag<std::map<Key, T, Compare, Allocator>>{});
}