Variadic Template,没有匹配的函数调用 [英] Variadic Template, no matching function call

查看:112
本文介绍了Variadic Template,没有匹配的函数调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个 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 ...>项目;

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;
}
//预期输出:
//1hihi0.2
//2jump8.3
// 3queue7
return 0;
}

编译时出现以下错误:

 错误:没有匹配的函数调用'commonLength(const Star :: List< int>& const Star :: List< std :: basic_string< char> ;&; const Star :: List< float>&)'
注意:候选是:
note:template< class ContainerA,class ... Containers> unsigned int Star :: commonLength(ContainerA,Containers ...,unsigned int)
注意: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&第一个){
unsigned firstLen = first.size();
if(len> firstLen){
len = firstLen;
}
return len;
}


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

template< template< typename ...> class Container,typename TypeA>
std :: tuple< TypeA> getTupleFrom index,Container< TypeA>常数& 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 ...>项目;

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;
}
//预期输出:
//1hihi0.2
//2jump8.3
// 3queue7
}

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




  • 您未在<$中使用 const& 容器c $ c> commonLength ,而 zip 是const引用的参数。

  • commonLength coudln't被推导,所以我把它移动到开头

  • 你声明/定义函数的顺序错误


显然,clang 3.1无法推导出<$中的模板参数c $ c> zip ,但g ++ 4.6让它们很好。


I'm writing an implementation of zip, but I've ran into a bit of a problem. Here's a minimal test case:

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

When compiling I get the following error:

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)

I'm assuming I'm specifying my template parameters wrong or something like that. I also attempted to restructure and eliminate that function altogether, but then I get the same error against getTupleFrom.

Can anyone explain to me why I'm stupid? Because I just don't know what I'm doing wrong. :(

解决方案

Well, this works:

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

It outputs exactly what you expected. The problems were:

  • You weren't using const& containers in commonLength, while zip's arguments where const references.
  • The unsigned parameter in commonLength coudln't be deduced, so I moved it to the beginning
  • You declared/defined functions in the wrong order(A required B, but A was defined before B), so I reordered them.

Apparently clang 3.1 fails to deduce the template arguments in zip, but g++ 4.6 gets them fine.

这篇关于Variadic Template,没有匹配的函数调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆