the question posed in: Type condition in template
is very similar, yet the original question wasn't quite answered.
#include "stdafx.h"
#include <type_traits>
class AA {
public:
double a;
double Plus(AA &b) {
return a + b.a;
}
};
template<class T> double doit(T &t) {
if (std::is_same<T, AA>::value)
return t.Plus(t);
else
return t + t;
}
int _tmain(int argc, _TCHAR* argv[])
{
double a;
AA aa;
doit(a);
doit(aa);
return 0;
}
This doesn't compile, nor did I expect it to. Is something like this possible? Being, based on the template value, I want some code to be compiled, and others not. Here, 'double' doesn't have a method called "Plus" and class "AA" doesn't override the '+' operator. Operator overloading isn't always desirable when considering subtle semantics to the operations, so I'm looking for an alternative. I'd prefer to do #ifdef's (truly conditional compilation as posed in the ref'd question), but based on template values.
This code compiles and runs:
Your code doesn't work because if the template is deduced as
AA
thent + t
inside the body is ill-formed. On the other hand ifT
is deduces asdouble
thent.Plus(t)
becomes ill-formed.To better understand what is happening: A template is instantiated for each template type is called with.
doIt(a)
instantiatesdoIt
withT = double
:doIt(aa)
instantiatesdoIt
withT = AA
:You should avoid specializing function templates because functions overload. You can read this excellent Herb Sutter article: Why Not Specialize Function Templates?
Since C++17 there is static if which is called if-constexpr. The following compiles fine since clang-3.9.1 and gcc-7.1.0, latest MSVC compiler 19.11.25506 handles well too with an option /std:c++17.
Overloading?
Explicit specialization is also possible, though superfluous:
What you want is a static if. C++ doesn't have it. There are many ways to work around it, none as good as native support. In addition to the methods specified in the other two answers, you could try tag dispatch.