内部模板类型的函数模板重载或特化 std::vector<std::vector<T>>
Function Template Overloading or Specialization for inner template type std::vector<std::vector<T>>
如何实现内部模板类型std::vector<std::vector<T>>
的函数模板重载std::vector<std::vector<T>>
。
我有一个重载模板程序和一个包含映射、对和向量的复杂数据结构。
#include <iostream>
#include <vector>
#include <map>
#include <utility>
#include <typeinfo>
template<typename Test, template<typename...> class Ref> //#6
struct is_specialization : std::false_type {};
template<template<typename...> class Ref, typename... Args> //#7
struct is_specialization<Ref<Args...>, Ref>: std::true_type {};
template <typename T>
bool f(T& x) // #1
{
std::cout << "body of f\n";
return f(x);
}
template <typename T>
bool f(std::vector<T>& v) // #2
{
std::cout << "body of f for vectors\n";
return true;
}
template<typename T>
typename std::enable_if<is_specialization<typename T::value, std::vector>::value, T>::type
bool f(std::vector<T>& v) // #5
{
std::cout << "body of f for vectors<vectors>\n";
return true;
}
template <typename Key, typename Value>
bool f(const std::pair<Key,Value>& v) // #3
{
std::cout << "body of f for pairs\n";
for(auto& e: v) {
f(e.first);
}
for(auto& e: v) {
f(e.second);
}
return true;
}
template <typename Key, typename Value>
bool f(std::map<Key,Value>& v) // #4
{
std::cout << "body of f for maps\n";
for(auto& e: v) {
f(e.first); // expecting this call goes to #3
}
for(auto& e: v) {
f(e.second);
}
return true;
}
int main() {
std::vector<int> v{1,2};
std::map<std::pair<int,int>,std::vector<std::vector<int>>> m_map = {
{{10,20}, {{5,6},{5,6,7}}},
{{11,22}, {{7,8},{7,8,9}}}
};
f(m_map); // this call goes to #4
}
总是调用向量 #2,但对于 std::vectors<std::vector<T>>
,我需要调用 #5,而且我遇到编译错误 w.r.t ::type used in std::enable_if .
请让我知道这个程序有什么问题以及如何让它工作。
还有人可以解释一下#6 和#7 表示什么 w.r.t 模板参数包,它是如何工作的。
谢谢。
我认为为 f()
编写 std::vector<std::vector<T>>
专业化的最简单方法如下
template<typename T>
bool f (std::vector<std::vector<T>>& v) // #5
{
std::cout << "body of f for vectors<vectors>\n";
return true;
}
这样你就重载了比 #2
.
更专业的模板 f()
函数
如果你想在你的 is_specialization
中使用 SFINAE,在我看来正确的方法如下
template <typename T>
typename std::enable_if<is_specialization<T, std::vector>::value, bool>::type
f (std::vector<T> & v) // #5
{
std::cout << "body of f for vectors<vectors>\n";
return true;
}
不幸的是,此版本专门用作版本 #2
,因此当您使用 std::vector<std::vector<T>>
调用 f()
时,会出现歧义,因此会出现编译错误。
要解决此问题,您还必须禁用 #2
版本
template <typename T>
typename std::enable_if<! is_specialization<T, std::vector>::value, bool>::type
f (std::vector<T> & v) // #2
{
std::cout << "body of f for vectors\n";
return true;
}
在您的原始版本中...您使用 typename T::type
...但是当 T
不是定义了 type
的 class 时会出现错误.
更多:你return两种类型
template<typename T>
typename std::enable_if<is_specialization<typename T::value,
std::vector>::value, T>::type // <<--- type 1: T
bool f(std::vector<T>& v) // #5
// ^^^^ type2: bool
以这种方式使用 SFINAE,returned 类型必须用 std::enable_if
表示
如何实现内部模板类型std::vector<std::vector<T>>
的函数模板重载std::vector<std::vector<T>>
。
我有一个重载模板程序和一个包含映射、对和向量的复杂数据结构。
#include <iostream>
#include <vector>
#include <map>
#include <utility>
#include <typeinfo>
template<typename Test, template<typename...> class Ref> //#6
struct is_specialization : std::false_type {};
template<template<typename...> class Ref, typename... Args> //#7
struct is_specialization<Ref<Args...>, Ref>: std::true_type {};
template <typename T>
bool f(T& x) // #1
{
std::cout << "body of f\n";
return f(x);
}
template <typename T>
bool f(std::vector<T>& v) // #2
{
std::cout << "body of f for vectors\n";
return true;
}
template<typename T>
typename std::enable_if<is_specialization<typename T::value, std::vector>::value, T>::type
bool f(std::vector<T>& v) // #5
{
std::cout << "body of f for vectors<vectors>\n";
return true;
}
template <typename Key, typename Value>
bool f(const std::pair<Key,Value>& v) // #3
{
std::cout << "body of f for pairs\n";
for(auto& e: v) {
f(e.first);
}
for(auto& e: v) {
f(e.second);
}
return true;
}
template <typename Key, typename Value>
bool f(std::map<Key,Value>& v) // #4
{
std::cout << "body of f for maps\n";
for(auto& e: v) {
f(e.first); // expecting this call goes to #3
}
for(auto& e: v) {
f(e.second);
}
return true;
}
int main() {
std::vector<int> v{1,2};
std::map<std::pair<int,int>,std::vector<std::vector<int>>> m_map = {
{{10,20}, {{5,6},{5,6,7}}},
{{11,22}, {{7,8},{7,8,9}}}
};
f(m_map); // this call goes to #4
}
总是调用向量 #2,但对于 std::vectors<std::vector<T>>
,我需要调用 #5,而且我遇到编译错误 w.r.t ::type used in std::enable_if .
请让我知道这个程序有什么问题以及如何让它工作。
还有人可以解释一下#6 和#7 表示什么 w.r.t 模板参数包,它是如何工作的。
谢谢。
我认为为 f()
编写 std::vector<std::vector<T>>
专业化的最简单方法如下
template<typename T>
bool f (std::vector<std::vector<T>>& v) // #5
{
std::cout << "body of f for vectors<vectors>\n";
return true;
}
这样你就重载了比 #2
.
f()
函数
如果你想在你的 is_specialization
中使用 SFINAE,在我看来正确的方法如下
template <typename T>
typename std::enable_if<is_specialization<T, std::vector>::value, bool>::type
f (std::vector<T> & v) // #5
{
std::cout << "body of f for vectors<vectors>\n";
return true;
}
不幸的是,此版本专门用作版本 #2
,因此当您使用 std::vector<std::vector<T>>
调用 f()
时,会出现歧义,因此会出现编译错误。
要解决此问题,您还必须禁用 #2
版本
template <typename T>
typename std::enable_if<! is_specialization<T, std::vector>::value, bool>::type
f (std::vector<T> & v) // #2
{
std::cout << "body of f for vectors\n";
return true;
}
在您的原始版本中...您使用 typename T::type
...但是当 T
不是定义了 type
的 class 时会出现错误.
更多:你return两种类型
template<typename T>
typename std::enable_if<is_specialization<typename T::value,
std::vector>::value, T>::type // <<--- type 1: T
bool f(std::vector<T>& v) // #5
// ^^^^ type2: bool
以这种方式使用 SFINAE,returned 类型必须用 std::enable_if