Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there anyway I can make a template<typename T> accept multiple values?

I wrote this code, and it currently can accept one void callback and pass one value to it. However, is there any way I can make the user able to set multiple args? Perhaps something like Callback Caller; instead of Callback without defining multiple typenames? Can I fit this all into one typename somehow?

For example, here is my class

template <typename T>
class Callback
{
private:
    std::vector<std::function <void (T)>> func;
public:
    virtual void operator += (std::function<void (T)> _func)
    {
        func.push_back(_func);
    }

};

I use it like this:

Callback<int> Test;

And it works just fine if I want to pass only one argument to my function. However, is it possible to make the user able to define multiple values, without having more than one typename?

I.e.

Callback< <(int, int, int)> > Test;

Something similar to that?

like image 378
Jason Avatar asked May 28 '13 23:05

Jason


People also ask

How will you restrict the template for a specific datatype?

There are ways to restrict the types you can use inside a template you write by using specific typedefs inside your template. This will ensure that the compilation of the template specialisation for a type that does not include that particular typedef will fail, so you can selectively support/not support certain types.

What is Typename C++?

Use the keyword typename if you have a qualified name that refers to a type and depends on a template parameter. Only use the keyword typename in template declarations and definitions.


1 Answers

In C++11, use variadic templates:

template <typename... Ts>
//                ^^^^^^ Parameter pack
class Callback
{
private:
    std::vector<std::function <void (Ts...)>> func;
//                                   ^^^^^
//                                   Parameter pack expansion
public:
    virtual void operator += (std::function<void (Ts...)> _func)
//                                                ^^^^^
//                             Parameter pack expansion             
    {
        func.push_back(_func);
    }
};

Now you can instantiate your class this way:

Callback<int, int, int>
Callback<double, std::string>
Callback<bool>
Callback<>
...
like image 135
Andy Prowl Avatar answered Oct 23 '22 13:10

Andy Prowl