无法推断出'TYPE'的模板参数

3

我有以下代码,它可以正常工作:

list <Politician> MakeList ( int num, ... ){
  va_list arguments;                     
  va_start ( arguments, num ); 
  list <Politician> PoliticianList;
  for ( int x = 0; x < num; x++ ) {
      PoliticianList.push_back(va_arg (arguments, Politician));
  }
  va_end ( arguments );                 

  return PoliticianList;       
}

然而,当试图使其通用化时:
template<class TYPE>
list <TYPE> MakeList ( int num, ... ){
  va_list arguments;                     
  va_start ( arguments, num ); 
  list <TYPE> PoliticianList;
  for ( int x = 0; x < num; x++ ) {
      PoliticianList.push_back(va_arg (arguments, TYPE));
  }
  va_end ( arguments );                 

  return PoliticianList;       
}

编译时我遇到了以下错误:

error C2783: 'std::list<TYPE> MakeList(int,...)' : could not deduce template argument for 'TYPE'

如何使代码通用化,以便不必为不同的类对象重新实现相同的功能?


2
你是怎么调用那个函数的? - Andy Prowl
如果你使用的是C++11,可变参数模板将是更好的选择。 - chris
1
你需要输入 MakeList<Foo>(3, foo1, foo2, foo3) - Kerrek SB
我无法重现您的问题:Live Code。您如何使用 MakeList - masoud
MakeList<Foo>(3, foo1, foo2, foo3) 解决了问题,非常感谢大家。 - Lior Avramov
显示剩余2条评论
1个回答

3

在调用模板版本的MakeList时,您需要明确提供TYPE的模板参数,因为仅根据您提供的参数,编译器无法知道TYPE应该是什么。例如,给定以下调用:

MakeList<Politician>(3, politician1, politician2, politician3)

编译器无法推断TYPE的类型。如果您希望它足够聪明并推断出您正在传递类型为Politician的对象作为参数,那么这是不可能的:C风格的可变参数函数在编译时不提供该信息。

然而,在C++11中,您可以使用可变模板来实现此目的,其中包括允许您将后续参数的数量作为第一个参数传递。以下是可能重写可变参数MakeList()的一种方式:

namespace detail
{
    template<typename T>
    void MakeList(std::list<typename std::remove_reference<T>::type>& l, T&& elem)
    {
        l.push_back(std::forward<T>(elem));
    }

    template<typename T, typename... Ts>
    void MakeList(
        std::list<typename std::remove_reference<T>::type>& l, 
        T&& elem, Ts&&... elems)
    {
        l.push_back(std::forward<T>(elem));
        MakeList(l, std::forward<Ts>(elems)...);
    }
}

template<typename T, typename... Ts>
std::list<typename std::remove_reference<T>::type> MakeList(
    T&& elem, Ts&&... elems)
{
    std::list<typename std::remove_reference<T>::type> l;
    detail::MakeList(l, std::forward<T>(elem), std::forward<Ts>(elems)...);
    return l;
}

您可以按照以下方式使用它:
int main()
{
    Politician p1{"John", "Smith"};
    Politician p2{"Mike", "Black"};
    Politician p3{"George", "White"};

    std::list<Politician> myList = MakeList(p1, p2, p3);

    for (auto const& p : myList)
    {
        std::cout << p.name << " " << p.surname << std::endl;
    }
}

Here is a live example.


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接