可变模板-编译错误

variadic templates - compile error

本文关键字:编译 错误      更新时间:2023-10-16

你能帮我修复下面代码中的编译错误吗?

#include <sstream>
#include <iostream>
using namespace std;
template<typename T, typename ...P>
class Mystrcat{
 public:
 Mystrcat(T t, P... p){init(t,p...);}
 ostringstream & get(){return o;}         
 private:
 ostringstream o;
 void init(){}
 void init(T t, P... p);
};
template<typename T, typename ...P>
void Mystrcat<T,P...>::init(T t, P ...p){
  o << t;
  if (sizeof...(p)) init(p...);
}
int main(){
 Mystrcat<char*,char *> m("Amma","Namasivayah");
 cout << m.get().str();
}

我得到错误,没有匹配的函数调用

‘Mystrcat<char*, char*>::init(char*&)’

注:候选人为:

void Mystrcat<T, P>::init() [with T = char*, P = char*]
void Mystrcat<T, P>::init(T, P ...) [with T = char*, P = char*]

gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)

谢谢苏雷什

您得到这个错误是因为没有办法将您的p解包到init函数中。在您的实例化Mystrcat<char*, char *>中,解包P...将在类型中产生一个东西:char*,它没有具有该签名的init(实例化版本将具有void init()void init(char*, char*),而您正在尝试调用init(char*))。

实际上,你的模板是不可能实例化的,因为init总是比void Mystrcat<T,P...>::init(T t, P ...p)多接受一个参数。如果您更改定义以调用已定义的内容:

template<typename T, typename ...P>
void Mystrcat<T,P...>::init(T t, P ...p){
  o << t;
  if (sizeof...(p)) init(t, p...);
}

那么这将工作(至少在g++-4.5.2)。


EDIT:我想这就是你实际要找的:

#include <sstream>
#include <iostream>
class MyCollector
{
public:
    template <typename... T>
    explicit MyCollector(const T&... args)
    {
        init(args...);
    }
    std::string str()
    {
        return _stream.str();
    }
private:
    void init()
    { }
    template <typename First, typename... Rest>
    void init(const First& first, const Rest&... rest)
    {
        _stream << first;
        init(rest...);
    }
    std::ostringstream _stream;
};
int main()
{
    MyCollector collector("Whatever ", "stuff like ", 2, " or ", 3.14, "n");
    std::cout << collector.str();
    return 0;
}