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.
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.
template<class T> double doit(T &t) {
if constexpr (std::is_same_v<T, AA>)
return t.Plus(t);
else
return t + t;
}
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.
template<class T> double doitImpl(T &t, std::true_type) {
return t.Plus(t);
}
template<class T> double doitImpl(T &t, std::false_type) {
return t+t;
}
template<class T> double doit(T &t) {
return doitImpl(t, std::is_same<T, AA>);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With