Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple typename arguments in c++ template?

Tags:

How can I have multiple typename arguments in a c++ template?

#ifndef _CALL_TEMP_H #define _CALL_TEMP_H  #include <string> #include <iostream>  template <typename Sig> class Foo;  template <typename A, typename B> class Foo {     public:         void output() {             std::cout << a_ << b_ << std::endl;         }         A a_;         B b_; };  template <typename A, typename B, typename C> class Foo {     public:         void output() {             std::cout << a_ << b_ << c_ << std::endl;         }         A a_;         B b_;         C c_; };  #endif 

Usage:

int main() {     Foo<int ,int> doubleint;     doubleint.a_ = 1;     doubleint.b_ = 2;     doubleint.output(); //  Foo<int , int , std::string> comp; //  comp.a_ = 1; //  comp.b_ = 2; //  comp.c_ = "haha"; //  comp.output();     return 0; } 

But it will not compile. How could I make it compile?

like image 390
Jichao Avatar asked Nov 12 '13 07:11

Jichao


People also ask

How can we use more than one argument with a function template?

Function Templates with Multiple Parameters of different types (in same function) We can use more than one generic type in the template function by using the comma to separate the list.

Can we pass Nontype parameters to templates?

Template classes and functions can make use of another kind of template parameter known as a non-type parameter. A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument.

What is typename in template?

" typename " is a keyword in the C++ programming language used when writing templates. It is used for specifying that a dependent name in a template definition or declaration is a type.

What is template argument list?

A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)


1 Answers

Just declare a primary template with a variadic template and then specialize for each supported number of template arguments. For example:

#ifndef CALL_TEMP_H #define CALL_TEMP_H  #include <iostream>  template <typename...> class Foo;  template <typename A, typename B> class Foo<A, B> { public:     void output() {         std::cout << a_ << b_ << '\n';     }     A a_;     B b_; };  template <typename A, typename B, typename C> class Foo<A, B, C> { public:     void output() {         std::cout << a_ << b_ << c_ << '\n';     }     A a_;     B b_;     C c_; };  #endif 

I you can't use C++11 and you want to retain a similar notation you'll need to simulate a variadic argument list with template default arguments. This will implicitly limit the number of templare arguments but since you are specializing the templates anyway, this limitation doesn't realky matter.

If it is acceptable to use a different notation you can also use something which looks like a function declaration to instantiate and specialize your template:

template <typename> class Foo;  template <typename A, typename B> class Foo<void(A, B)> {     ... }; template <typename A, typename B, typename C> class Foo<void(A, B, C)> {     ... }; ... Foo<void(int, int)>                   f2; Foo<void(int, int, std::string)> f3; 

Whether the change in notation is acceptable depends on your use of the class template. You won't achieve an ideal solution as with variadic templates without C++11, though.

BTW, don't overuse std::endl: use '\n' to mean end of line. If you really mean to flush the stream, use std::flush. Also _CALL_TEMP_H is a name reserved to the standard C++ library as are all names starting with an underscore followed by a capital character: do not use these names in your own code unless there is explicit permission to use them (e.g. __FILE__ and __LINE__ are reserved but explicit permission to use them is granted).

like image 127
Dietmar Kühl Avatar answered Sep 20 '22 17:09

Dietmar Kühl