if / else at compile time in C++?
The simplest fix is partial template specialization:
template<typename T> class MyClassBase
{
public:
MyClassBase() : myVar{0} {;}
protected:
T myVar;
};
template<typename T> class MyClass: MyClassBase<T>
{
public:
void testIf() { myVar = 3; }
};
template<typename T> class MyClass<const T>: MyClassBase<const T>
{
public:
void testIf() { myVar; }
};
Another option is delegation:
template<typename T> class MyClass
{
public:
MyClass() : myVar{0} {;}
void testIf() { testIf_impl(std::integral_constant<bool, isconst>()); }
protected:
static const bool isconst = std::is_const<T>::value;
T myVar;
private:
void testIf_impl(std::true_type) { myvar; }
void testIf_impl(std::false_type) { myVar = 3; }
};
SFINAE is another option, but is generally not preferred for this case:
template<typename T> class MyClass
{
public:
MyClass() : myVar{0} {;}
template
<typename U = void>
typename std::enable_if<std::is_const<T>::value, U>::type testIf() { myvar; }
template
<typename U = void>
typename std::enable_if<!std::is_const<T>::value, U>::type testIf() { myvar = 3; }
protected:
static const bool isconst = std::is_const<T>::value;
T myVar;
};
C++17 if constexpr
Oh yes, it has arrived:
main.cpp
#include <cassert>
#include <type_traits>
template<typename T>
class MyClass {
public:
MyClass() : myVar{0} {}
void modifyIfNotConst() {
if constexpr(!isconst) {
myVar = 1;
}
}
T myVar;
protected:
static constexpr bool isconst = std::is_const<T>::value;
};
int main() {
MyClass<double> x;
MyClass<const double> y;
x.modifyIfNotConst();
y.modifyIfNotConst();
assert(x.myVar == 1);
assert(y.myVar == 0);
return 0;
}
GitHub upstream.
Compile and run:
g++-8 -std=c++17 -Wall -Wextra -pedantic -o main.out main.cpp
./main.out
See also: Difference between "if constexpr()" Vs "if()"
This will be really cool together with C++20 "string literal template arguments": Passing a string literal as a parameter to a C++ template class
Tested in Ubuntu 16.04, GCC 8.1.0.