variadic templates - compile error

Discussion in 'C++' started by suresh, Aug 19, 2011.

  1. suresh

    suresh Guest

    Hi,
    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*&)’

    gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)

    Thanks
    suresh
    suresh, Aug 19, 2011
    #1
    1. Advertising

  2. suresh

    SG Guest

    On 19 Aug., 01:31, suresh <> wrote:
    > Hi,
    > 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*&)’


    Your Mystrcat<char*,char*> ohly has two init functions:
    - void init()
    - void init(char*,char*)

    and inside the second one, you're trying to call some nonexistinc init
    with just a single parameter.

    Also, I fail to see the benefit of a class here. Why not simply:

    inline void strcat_helper(ostream & os) {} // nothing to do

    template<class T, class... More>
    inline void strcat_helper(ostream & os, T && t, More &&... more)
    {
    os << forward<T>(t);
    strcat_helper(os,forward<More>(more)...);
    }

    template<class... Args>
    string strcat(Args &&... args)
    {
    ostringstream os;
    strcat_helper(os,forward<Args>(args)...);
    return os.str();
    }

    SG
    SG, Aug 19, 2011
    #2
    1. Advertising

  3. suresh

    suresh Guest

    thank you SG for your code. It compiles and runs correctly. But I am unable to understand the code. Could you kindly explain:
    (1) what is forward<T> ?
    (2) Why && in the argument?

    Thanks again
    suresh
    suresh, Aug 19, 2011
    #3
  4. suresh

    suresh Guest

    Hi SG,
    thank you very much for the code. But I could not understand this. Could you explain forward <T> and the usage of &&.
    thanks
    suresh

    On Thursday, 18 August 2011 21:56:32 UTC-7, SG wrote:
    > On 19 Aug., 01:31, suresh <> wrote:
    > > Hi,
    > > 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*&)’

    >
    > Your Mystrcat<char*,char*> ohly has two init functions:
    > - void init()
    > - void init(char*,char*)
    >
    > and inside the second one, you're trying to call some nonexistinc init
    > with just a single parameter.
    >
    > Also, I fail to see the benefit of a class here. Why not simply:
    >
    > inline void strcat_helper(ostream & os) {} // nothing to do
    >
    > template<class T, class... More>
    > inline void strcat_helper(ostream & os, T && t, More &&... more)
    > {
    > os << forward<T>(t);
    > strcat_helper(os,forward<More>(more)...);
    > }
    >
    > template<class... Args>
    > string strcat(Args &&... args)
    > {
    > ostringstream os;
    > strcat_helper(os,forward<Args>(args)...);
    > return os.str();
    > }
    >
    > SG




    On Thursday, 18 August 2011 21:56:32 UTC-7, SG wrote:
    > On 19 Aug., 01:31, suresh <> wrote:
    > > Hi,
    > > 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*&)’

    >
    > Your Mystrcat<char*,char*> ohly has two init functions:
    > - void init()
    > - void init(char*,char*)
    >
    > and inside the second one, you're trying to call some nonexistinc init
    > with just a single parameter.
    >
    > Also, I fail to see the benefit of a class here. Why not simply:
    >
    > inline void strcat_helper(ostream & os) {} // nothing to do
    >
    > template<class T, class... More>
    > inline void strcat_helper(ostream & os, T && t, More &&... more)
    > {
    > os << forward<T>(t);
    > strcat_helper(os,forward<More>(more)...);
    > }
    >
    > template<class... Args>
    > string strcat(Args &&... args)
    > {
    > ostringstream os;
    > strcat_helper(os,forward<Args>(args)...);
    > return os.str();
    > }
    >
    > SG




    On Thursday, 18 August 2011 21:56:32 UTC-7, SG wrote:
    > On 19 Aug., 01:31, suresh <> wrote:
    > > Hi,
    > > 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*&)’

    >
    > Your Mystrcat<char*,char*> ohly has two init functions:
    > - void init()
    > - void init(char*,char*)
    >
    > and inside the second one, you're trying to call some nonexistinc init
    > with just a single parameter.
    >
    > Also, I fail to see the benefit of a class here. Why not simply:
    >
    > inline void strcat_helper(ostream & os) {} // nothing to do
    >
    > template<class T, class... More>
    > inline void strcat_helper(ostream & os, T && t, More &&... more)
    > {
    > os << forward<T>(t);
    > strcat_helper(os,forward<More>(more)...);
    > }
    >
    > template<class... Args>
    > string strcat(Args &&... args)
    > {
    > ostringstream os;
    > strcat_helper(os,forward<Args>(args)...);
    > return os.str();
    > }
    >
    > SG




    On Thursday, 18 August 2011 21:56:32 UTC-7, SG wrote:
    > On 19 Aug., 01:31, suresh <> wrote:
    > > Hi,
    > > 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*&)’

    >
    > Your Mystrcat<char*,char*> ohly has two init functions:
    > - void init()
    > - void init(char*,char*)
    >
    > and inside the second one, you're trying to call some nonexistinc init
    > with just a single parameter.
    >
    > Also, I fail to see the benefit of a class here. Why not simply:
    >
    > inline void strcat_helper(ostream & os) {} // nothing to do
    >
    > template<class T, class... More>
    > inline void strcat_helper(ostream & os, T && t, More &&... more)
    > {
    > os << forward<T>(t);
    > strcat_helper(os,forward<More>(more)...);
    > }
    >
    > template<class... Args>
    > string strcat(Args &&... args)
    > {
    > ostringstream os;
    > strcat_helper(os,forward<Args>(args)...);
    > return os.str();
    > }
    >
    > SG
    suresh, Aug 19, 2011
    #4
  5. suresh

    SG Guest

    On 19 Aug., 09:38, suresh wrote:
    > thank you SG for your code. It compiles and runs correctly.
    > But I am unable to understand the code. Could you kindly explain:
    > (1) what is forward<T> ?
    > (2) Why && in the argument?


    std::forward<> ist a Helper function from the <utility> header that is
    supposed to be used for "perfect forwarding". Perfect forwarding is
    about forwarding function arguments to another function while
    retaining
    - the original type
    - the original "l/r valueness"

    Both properties are (in this case) encoded in the type T and the
    forward<T>() call restores these properties, more specifically, the
    correct kind of valueness.

    Examples:

    void foo(const int&); // #1
    void foo(int &&); // #2

    template<class T> void bar(T&& x) {
    foo(forward<T>(x));
    }

    int main() {
    int i = 42;
    bar(9); // --> T=int --> T&&=int&& --> #2
    bar(i); // --> T=int& --> T&&=int& --> #1
    }

    SG
    SG, Aug 19, 2011
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Colin Walters
    Replies:
    2
    Views:
    522
    Ben Pfaff
    Feb 13, 2004
  2. Ross A. Finlayson
    Replies:
    19
    Views:
    598
    Keith Thompson
    Mar 10, 2005
  3. Replies:
    2
    Views:
    345
    Dave Thompson
    Feb 27, 2006
  4. Replies:
    5
    Views:
    363
  5. Valeriu Catina

    c++0x variadic templates

    Valeriu Catina, Mar 13, 2008, in forum: C++
    Replies:
    3
    Views:
    609
    Erik Wikström
    Mar 13, 2008
Loading...

Share This Page