Home > Back-end >  Usage of decltype in return type of function template removes error due to exception specification
Usage of decltype in return type of function template removes error due to exception specification

Time:03-18

I saw an answer to a question here. There the author of the answer made use of the fact that

exception specifications do not participate1 in template argument deduction.

In the answer linked above it is explained why the following doesn't compile:

#include <iostream>

template<typename T>
void timer(T a) noexcept(func(T()))
{
    std::cout<<"template timer called"<<std::endl;
}

void timer(...)
{
    std::cout<<"ordinary timer called"<<std::endl;   
}
int main()
{
    timer(5);//won't compile
    return 0;
}

it is said that because exception specification do not participate in TAD, overload resolution selects the function template version and so when the exception specification is instantiated at later time, the program becomes ill-formed and we get the error.

Now i modified the above program to see if i understand the topic correctly. In particular, i have added decltype(func(T())) as the return type of the function template version(as shown below) and then the error goes away:

template<typename T>
decltype(func(T())) timer(T a) noexcept(func(T())) //return type added here
{
    std::cout<<"template timer called"<<std::endl;
    return func(T());//return statement added here
}

void timer(...)
{
    std::cout<<"ordinary timer called"<<std::endl;   
}
int main()
{
    timer(5); //works now? 
    return 0;
}

My question is, why when we add the return type to the function template as shown above, the error has gone away?

PS: My question is not about why the first example gives error works but it is rather why the modified example doesn't give error.


1This quote is from C Templates: The Complete Guide.

CodePudding user response:

Here since there is no func, so during the substitution of the template argument(s) in the return type of the function template, we get substitution failure and due to SFINAE this function template is not added to the set. In other words, it is ignored.

Thus the call timer(5); uses the ordinary function timer since it is the only viable option now that the function template has been ignored. Hence the program compiles and gives the output:

ordinary timer called
  • Related