gpt4 book ai didi

c++ - 模棱两可的重载模板

转载 作者:行者123 更新时间:2023-12-01 09:13:51 25 4
gpt4 key购买 nike

我有以下模板化代码

#include <vector>
#include <array>
#include <iostream>

template<typename T1>
void foo(std::vector<T1> bar) {
std::cout << "GENERIC" << std::endl;
}

template<typename T1>
void foo(std::vector<std::vector<T1>> bar) {
std::cout << "SPECIFIC (vector)" << std::endl;
}

template<typename T1, int SIZE>
void foo(std::vector<std::array<T1, SIZE>> bar) {
std::cout << "SPECIFIC (array)" << std::endl;
}

int main() {
std::vector<std::vector<int>> a(2, std::vector<int> { 1, 2, 3});
std::vector<std::array<int, 3>> b(2, std::array<int, 3> {4, 5, 6});

foo(a);
foo(b);
}

产生
SPECIFIC (vector)
GENERIC

我想知道为什么使用特定模板调用 vector-of-vector 版本,而使用泛型调用 vector-of-array 版本?

最佳答案

template<typename T1, size_t SIZE>
void foo(std::vector<std::array<T1, SIZE>> bar) {
std::cout << "SPECIFIC (array)" << std::endl;
}

您应该使用 std::size_t而不是 int .
run here

编辑:
实际上,您的评论和我对代码的直觉使我深入研究了该主题。乍一看,标准开发人员(像我一样)希望编译器能够转换 intstd::size_t (因为它们都是整数类型并且隐式转换非常简单)并选择 void foo(std::vector<std::array<T1, SIZE>> bar)作为最好的专业。所以在阅读时 template argument deduction我发现这个页面:

If a non-type template parameter is used in the parameter list, and the corresponding template argument is deduced, the type of the deduced template argument ( as specified in its enclosing template parameter list, meaning references are preserved) must match the type of the non-type template parameter exactly, except that cv-qualifiers are dropped, and except where the template argument is deduced from an array bound—in that case any integral type is allowed, even bool though it would always become true:



与往常一样,当然,您必须多读几遍才能理解它的含义:)

于是一个有趣的结果出来了。

已经没有选择我们想要的特化,但如果编译器被迫选择,那将是一个错误。
template<typename T1, int SIZE>
void foo(std::vector<std::array<T1, SIZE>> bar) {
std::cout << "SPECIFIC (array)" << std::endl;
}

int main() {
std::vector<std::array<int, 3>> b(2, std::array<int, 3> {4, 5, 6});

foo(b); // P = std::vector<std::array<int,(int)SIZE>
// A = std::vector<std::array<int,(unsigned_long)SIZE>>
// error: deduced non-type template argument does not have the same
// type as its corresponding template argument */
}

run code

另一个有趣的事情是:

如果没有推导出非类型模板参数,则不会有强制参数和模板类型相同的限制。
#include <vector>
#include <array>
#include <iostream>

template<typename T1, int SIZE>
void foo(std::vector<std::array<T1, SIZE>> bar) {
std::cout << "SPECIFIC (array)" << std::endl;
}

int main() {
std::vector<std::array<int, 3>> b(2, std::array<int, 3> {4, 5, 6});

foo<int,3>(b);
}

run code

关于c++ - 模棱两可的重载模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60207971/

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