可变参数模板 - 编译错误

发布于 2024-11-30 11:45:51 字数 925 浏览 1 评论 0原文

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

#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版本4.4.3(Ubuntu 4.4.3-4ubuntu5)

谢谢 苏雷什

Could you help me in fixing the compile error in the following code:

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

I get the error, no matching function for call to

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

note: candidates are:

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)

Thanks
suresh

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清君侧 2024-12-07 11:45:51

您收到此错误是因为无法将 p 解压到任一 init 函数中。在实例化 Mystrcat 中,解压 P... 将产生以下类型的单个内容:char*,它没有带有该签名的 init (实例化版本将具有 void init()void init(char*, char*),而您正在尝试调用init(char*))。

事实上,你的模板是不可能实例化的,因为 init 总是比你在 void Mystrcat::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 中)。


编辑:我认为这就是您真正想要的:

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

You're getting this error because there isn't a way to unpack your p into either init function. In your instantiation Mystrcat<char*, char *>, unpacking a P... will yield a single thing in the type: char*, which doesn't have an init with that signature (the instantiated version will have a void init() and void init(char*, char*), whereas you are trying to call init(char*)).

In fact, your template is impossible to instantiate, since init will always take one more argument than you give it in void Mystrcat<T,P...>::init(T t, P ...p). If you change the definition to call what you have defined:

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

then this will work (at least in g++-4.5.2).


EDIT: I think this is what you're actually looking for:

#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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文