我有以下代码可以正常工作:
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'
如何使其成为通用的,所以我不必为不同的类对象重新实现?
答案 0 :(得分:3)
在调用TYPE
的模板化版本时,您需要为MakeList
显式提供模板参数,因为编译器根据您提供的参数不知道{{1} }} 应该。例如,给出以下呼叫:
TYPE
编译器无法推断MakeList<Politician>(3, politician1, politician2, politician3)
是什么。如果你期望它足够聪明并且推断你传递类型TYPE
的对象作为参数,那么这将无效:C风格的可变参数函数在编译时根本不提供该信息。
但是,在C ++ 11中,您可以使用可变参数模板来实现此目的,除此之外,它还允许不传递后续参数的数量,如第一个论点。您可以通过以下方式重写变量Politician
:
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;
}
这是live example。