gpt4 book ai didi

c++ - 嵌套模板函数的重载

转载 作者:行者123 更新时间:2023-12-01 14:34:02 25 4
gpt4 key购买 nike

我想了很多我的问题的标题,但还是失败了,所以如果你找到一个好的标题,请编辑它。

我正在尝试为 vector 编写打印函数或其他container<T>并为 container<container<T>> 提供另一个打印功能,所以这是我想出的:

template<typename T>
void print(T const& cont){
for (const auto& i : cont) {
cout << i << " ";
}
cout << endl;
}

template<typename T, template<typename> typename Cont>
void print(Cont<T> const& cont) {
for (const auto& i : cont) {
print(i);
}
}

这里有我的 2 个目标容器:

vector<vector<int>> subsets;
vector<int> subset;

当我调用 print(subset); 时该程序按预期工作,但是当我调用 print(subsets) 时,编译器开始提示:

error C2679: binary '<<': no operator found which takes a right-hand operand of type 'const std::vector<int,std::allocator<int>>' (or there is no acceptable conversion)

我的结论是,它仍在尝试调用非嵌套模板打印函数,但在 cout 上失败了。因为我正在尝试计算一个 vector 。

谁能解释为什么重载决议没有按我预期的那样工作以及我在这里做错了什么?即使我将嵌套模板函数重命名为 printn,它也会因为不同的原因开始提示:

error C2784: 'void prints(const Cont<T> &)': could not deduce template argument for 'const Cont<T> &' from 'std::vector<std::vector<int,std::allocator<int>>,std::allocator<std::vector<int,std::allocator<int>>>>'

最佳答案

简短、简单但不充分的答案是 std::vector有 2 个模板参数。您还应该包含一些间距:

template<class T, class A, template<class, class>class C>
void print(C<T,A> const& cont) {
std::cout << "[ ";
bool bFirst = true;
for (const auto& i : cont) {
if (!bFirst)
std::cout << ", ";
bFirst = false;
print(i);
}
std::cout << " ]";
}

因此从未调用过重载。

一旦执行此操作,您的代码将无法运行,因为您没有元素打印机。所以用元素打印机替换你的其他循环打印机:

template<typename T>
void print(T const& i){
std::cout << i;
}

Live example .

测试代码:

std::vector<int> a={1,2,3};
print(a);
std::cout << "\n";
std::vector<std::vector<int>> b = {a, a, a};
print(b);
std::cout << "\n";

输出:

[ 1, 2, 3 ]
[ [ 1, 2, 3 ], [ 1, 2, 3 ], [ 1, 2, 3 ] ]

这是不够的,因为如果您想要一个更严肃的通用打印机,您真的应该做一些更有趣的事情来检测“这个对象是否可迭代”和“这个对象是否类似元组”。检测Cont<A,B>模板是一个糟糕的替代品。

Here是检测某物是否可迭代的代码(忽略错误的检查答案,阅读我链接到的那个)。

然后对 print 中的“参数是否可迭代”进行 SFINAE 测试对于做 for(:) 的那个循环。

接下来您要做的是检测对象是否类似于元组。如果是,您想要打印出元组的每个元素。这给你std::mapstd::unordered_map支持。请注意 std::array既像元组又可迭代。

这比检测“可迭代”要难一些,并且随着您使用的 C++ 标准的不同而变化更大,因为类元组正在随着新版本的 C++ 扩展。你可以偷懒,只检测std::pairstd::tuple ,这将涵盖 99% 的用例。

关于c++ - 嵌套模板函数的重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62088106/

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