Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I explicitly specify template arguments for an operator?

Tags:

c++

I have the class Foo:

class Foo {
    template <typename T>
    T* operator () (void) {
        return (T*) something;
    }
}

T can't be deduced, but what I want is to be able to say something like

Foo foo;    
type_t bar = foo <type_t> ();

But this is a syntax error.

Is there a way to do this? (or perhaps some better way to pass in a type without providing an instance of the type?)

like image 890
evenex_code Avatar asked Mar 14 '14 17:03

evenex_code


People also ask

Can we use non-type parameters as arguments template?

Non-type template arguments are normally used to initialize a class or to specify the sizes of class members. For non-type integral arguments, the instance argument matches the corresponding template parameter as long as the instance argument has a value and sign appropriate to the parameter type.

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.

How do you use template arguments in C++?

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.)

What is template argument deduction in C++?

Class Template Argument Deduction (CTAD) is a C++17 Core Language feature that reduces code verbosity. C++17's Standard Library also supports CTAD, so after upgrading your toolset, you can take advantage of this new feature when using STL types like std::pair and std::vector.


2 Answers

You can do it using the operator name syntax:

type_t *bar = foo.operator() <type_t> ();

That's of course ugly. There are two solutions:

  1. Change the operator so that it takes a parameter and thus the type is deducible.

  2. Change it from an operator to a named function. It doesn't seem like a typical use for operator() anyway.

like image 138
Angew is no longer proud of SO Avatar answered Oct 03 '22 15:10

Angew is no longer proud of SO


Here's an example which compiles and runs:

struct Foo {
    template <typename T>
    T* operator () () {
        return (T*) 0;
    }
};

int main()
{
    double* bar = Foo().operator()<double>();
}

But that's really ugly. It is a clear case of operator-overloading abuse. Consider using an ordinary function name. Operator overloading should make code faster to read, not the opposite.

like image 39
Christian Hackl Avatar answered Oct 03 '22 14:10

Christian Hackl