gpt4 book ai didi

c++ - 可变参数模板,没有匹配的函数调用

转载 作者:行者123 更新时间:2023-11-30 02:03:49 27 4
gpt4 key购买 nike

我正在编写 zip 的实现,但遇到了一些问题。这是一个最小的测试用例:

#include <iostream>
#include <deque>
#include <tuple>
#include <string>
#include <limits>

template <template <typename...> class Container, typename... Types>
Container<std::tuple<Types...>> zip(Container<Types> const&... args) {
unsigned len = commonLength(args...);
Container<std::tuple<Types...>> res;
std::tuple<Types...> item;

for (unsigned i=0; i<len; i++) {
item = getTupleFrom(i, args...);
res.push_back(item);
}

return res;
}

template <class ContainerA, class... Containers>
unsigned commonLength(ContainerA first, Containers... rest, unsigned len=std::numeric_limits<unsigned>::max()) {
unsigned firstLen = first.size();
if (len > firstLen) {
len = firstLen;
}
return commonLength(rest..., len);
}

template <class ContainerA>
unsigned commonLength(ContainerA first, unsigned len=std::numeric_limits<unsigned>::max()) {
unsigned firstLen = first.size();
if (len > firstLen) {
len = firstLen;
}
return len;
}

template <template <typename...> class Container, typename TypeA, typename... Types>
std::tuple<TypeA, Types...> getTupleFrom(unsigned index, Container<TypeA> const& first, Container<Types> const&... rest) {
return std::tuple_cat(std::tuple<TypeA>(first[index]), getTupleFrom(index, rest...));
}

template <template <typename...> class Container, typename TypeA>
std::tuple<TypeA> getTupleFrom(unsigned index, Container<TypeA> const& first) {
return std::tuple<TypeA>(first[index]);
}

int main() {

std::deque<int> test1 = {1, 2, 3, 4};
std::deque<std::string> test2 = {"hihi", "jump", "queue"};
std::deque<float> test3 = {0.2, 8.3, 7, 123, 2.3};
for (auto i : zip(test1, test2, test3)) {
std::cout << std::get<0>(i) << std::get<1>(i) << std::get<2>(i) << std::endl;
}
//expected output:
//1hihi0.2
//2jump8.3
//3queue7
return 0;
}

编译时出现以下错误:

error: no matching function for call to ‘commonLength(const Star::List<int>&, const Star::List<std::basic_string<char> >&, const Star::List<float>&)’
note: candidates are:
note: template<class ContainerA, class ... Containers> unsigned int Star::commonLength(ContainerA, Containers ..., unsigned int)
note: template<class ContainerA> unsigned int Star::commonLength(ContainerA, unsigned int)

我假设我指定的模板参数有误或类似情况。我还尝试重组并完全消除该函数,但随后我在 getTupleFrom 上遇到了同样的错误。

谁能给我解释一下我为什么这么笨?因为我只是不知道我做错了什么。 :(

最佳答案

好吧,这行得通:

#include <iostream>
#include <deque>
#include <tuple>
#include <string>
#include <type_traits>
#include <algorithm>
#include <limits>

template <class ContainerA>
unsigned commonLength(unsigned len, const ContainerA &first) {
unsigned firstLen = first.size();
if (len > firstLen) {
len = firstLen;
}
return len;
}


template <class ContainerA, class... Containers>
unsigned commonLength(unsigned len, const ContainerA &first, const Containers&... rest) {
unsigned firstLen = first.size();
if (len > firstLen) {
len = firstLen;
}
return commonLength(len, rest...);
}

template <template <typename...> class Container, typename TypeA>
std::tuple<TypeA> getTupleFrom(unsigned index, Container<TypeA> const& first) {
return std::tuple<TypeA>(first[index]);
}

template <template <typename...> class Container, typename TypeA, typename... Types>
std::tuple<TypeA, Types...> getTupleFrom(unsigned index, Container<TypeA> const& first, Container<Types> const&... rest) {
return std::tuple_cat(std::tuple<TypeA>(first[index]), getTupleFrom(index, rest...));
}

template <template <typename...> class Container, typename... Types>
Container<std::tuple<Types...>> zip(Container<Types> const&... args) {
unsigned len = commonLength(std::numeric_limits<unsigned>::max(), args...);
Container<std::tuple<Types...>> res;
std::tuple<Types...> item;

for (unsigned i=0; i<len; i++) {
item = getTupleFrom(i, args...);
res.push_back(item);
}

return res;
}

int main() {

std::deque<int> test1 = {1, 2, 3, 4};
std::deque<std::string> test2 = {"hihi", "jump", "queue"};
std::deque<float> test3 = {0.2, 8.3, 7, 123, 2.3};
for (auto i : zip(test1, test2, test3)) {
std::cout << std::get<0>(i) << std::get<1>(i) << std::get<2>(i) << std::endl;
}
//expected output:
//1hihi0.2
//2jump8.3
//3queue7
}

它的输出完全符合您的预期。问题是:

  • 您没有在 commonLength 中使用 const& 容器,而 zip 的参数引用了 const。
  • commonLength中的unsigned参数无法推导,所以移到开头
  • 您以错误的顺序声明/定义了函数(A 需要 B,但 A 是在 B 之前定义的),所以我重新排序了它们。

显然 clang 3.1 无法推断出 zip 中的模板参数,但 g++ 4.6 可以正常使用它们。

关于c++ - 可变参数模板,没有匹配的函数调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11397484/

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