【问题标题】:Could not Deduce Template Argument for 'TYPE'无法推断“类型”的模板参数
【发布时间】:2013-05-25 04:22:39
【问题描述】:

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

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'

我怎样才能使它通用,这样我就不必为不同的类对象重新实现?

【问题讨论】:

  • 你是怎么调用那个函数的?
  • 如果你有 C++11,可变参数模板会是更好的选择。
  • 你必须说MakeList&lt;Foo&gt;(3, foo1, foo2, foo3)
  • 我无法重现您的问题:Live Code。你是如何使用MakeList 的?
  • MakeList(3, foo1, foo2, foo3)

标签: c++ templates


【解决方案1】:

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

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

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

但是,在 C++11 中,您可以使用 variadic templates 来实现此目的,这将允许您 not 将后续参数的数量传递为第一个论点。这是一种可能的方式,您可以重写您的可变参数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;
    }
}

这是live example

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 2015-02-06
    • 2013-02-18
    相关资源
    最近更新 更多