gpt4 book ai didi

c++ - 内部模板类型 std::vector> 的函数模板重载或专门化

转载 作者:行者123 更新时间:2023-12-02 06:22:44 25 4
gpt4 key购买 nike

如何实现内部模板类型的函数模板重载std::vector<std::vector<T>> .

我有一个重载模板的程序和一个包含 map 、对和 vector 的复杂数据结构。

#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
}

对于 vector #2 总是被调用,但是对于 std::vectors<std::vector<T>>我需要 #5 才能被调用,而且我还收到了 std::enable_if 中使用的 w.r.t::type 编译错误。请让我知道这个程序有什么问题以及如何使它工作。另外有人可以解释一下 #6 和 #7 代表什么模板参数包,它是如何工作的。

谢谢。

最佳答案

我看到的最简单的写法 std::vector<std::vector<T>>特化f()如下

template<typename T>
bool f (std::vector<std::vector<T>>& v) // #5
{
std::cout << "body of f for vectors<vectors>\n";
return true;
}

这样你就重载了模板f()#2 更专业的函数.

如果您想将 SFINAE 与 is_specialization 一起使用,在我看来,正确的方法如下

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 ,所以当您调用f()时与 std::vector<std::vector<T>> ,你会得到一个歧义,因此会出现编译错误。

要解决此问题,您还必须禁用 #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 的类已定义。

更多:您返回两种类型

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,返回的类型必须用 std::enable_if 来表示

关于c++ - 内部模板类型 std::vector<std::vector<T>> 的函数模板重载或专门化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59464774/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com