Variadic模板,没有匹配的函数调用
Variadic Template, no matching function call
我正在编写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
中的无符号参数无法推导,所以我把它移到了开头- 您以错误的顺序声明/定义了函数(A需要B,但A是在B之前定义的),所以我对它们进行了重新排序
显然,clang 3.1未能推导出zip
中的模板参数,但g++4.6可以很好地推导出它们。
逐步拾取。
您缺少标题:
#include <limits>
您有未声明的标识符:
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...), end);
}
end
在哪里声明?
您不一致:
Container<std::tuple<Types...>> zip(Container<Types> const&... args) {
unsigned len = commonLength(args...);
Container<std::tuple<Types...>> res;
是Container<std::tuple<Types...>>
还是Container<Types>
?或者这正是你的意思?您的代码有点复杂,只需快速查看即可。
那么,对于Container<TypeA>
的非零计数,您只有getTupleFrom
的版本,
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...), end);
}
template <template <typename...> class Container, typename TypeA>
std::tuple<TypeA> getTupleFrom(unsigned index, Container<TypeA> const& first) {
return std::tuple<TypeA>(first[index]);
}
这就是出现错误的原因
error: no matching function for call to ‘getTupleFrom(unsigned int&)’
这表明您以某种方式达到了参数列表为空的点(无符号整数参数除外)。我想你需要防止这种情况发生。
相关文章:
- 模板函数调用
- 如何在主函数中调用模板类
- C++11:模板方法的模板函数调用无法编译?
- 如何循环调用模板函数?
- 为变量模板的每个参数调用模板函数
- 调用模板提供的(静态)函数
- 根据参数的数量调用模板中的函数
- 模板和无效函数调用C++
- 使用显式模板参数列表和 [temp.arg.explicit]/3 的函数调用的演绎失败
- 如何调用模板类型的正确构造函数?
- 通过指针调用模板类成员函数 [为什么这是有效的 c++]?
- lambda 函数使用其参数作为模板参数调用模板函数
- 从模板化函数调用非模板化函数
- 模棱两可的调用 - 模板化函数
- 可变参数模板函数:调用没有匹配函数,std::endl
- 如何在使用模板的函数调用的大括号表达式中推导多维数组的大小
- 如何在 c++ 中从模板基类的构造函数调用模板超类的构造函数?
- 为什么它是一个使用GCC的令人震惊的函数调用?模板扣减失败
- 为什么我不能从模板化函数调用模板化类的模板化方法
- c++从另一个模板函数调用模板函数