Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When are template arguments required in C++?

I am curious as to when template arguments are required in C++.

For example, let's define a class as

template<typename T> class Add {
    T value;
public:
    Add(T value) : value(value){};

    T operator() (T valrhs){
        return value + valrhs; 
    }
};

If we wanted to create an object of type Add using double, we would need to define it as follows to not get errors,

Add<double> add5 = Add<double>(5.0);

Lets now consider a function defined as follows,

template<typename T, typename Function> T doOperation (T data, Function f){
    return f(data);
}

In code, if one was to make a call to doOperation, no template arguments would be needed. For example,

std::cout << doOperation(5.0, add5);

would output 10. Why is it that doOperation does not require template arguments but the defining add5 required template arguments?

Also, would there be any way to define this using function pointers. I have been stuck trying to figure out how to pass a functor like this using a function pointer as a parameter variable rather than a second template argument.

Thanks, any help is appreciated.

like image 538
Franklin V Avatar asked Nov 30 '22 21:11

Franklin V


1 Answers

In this code

std::cout << doOperation(5.0, add5);

The compiler does function-template argument deduction.

In this line

Add<double> add5 = Add<double>(5.0);

you need to provide the template arguments since the compiler won't do class-template argument deduction.

However, from c++17, the compiler will do class-template argument deduction, and then this compiles just fine

Add add5(5.0);

You can provide the deduction guide explicitly as well, since that may be needed in some cases

template<typename T>  Add(T) -> Add<T>;

On a side-note, your class Add looks like it could be replaced by a function-template that returns a lambda.

template<typename T>
auto Add (T value) { 
    return [value] (T valrhs) { 
        return value + valrhs; 
    }; 
}

The usage would then look like

auto add5 = Add(5.0);
std::cout << doOperation(5.0, add5);
like image 141
cigien Avatar answered Dec 11 '22 12:12

cigien