An alternative version that uses a single function might be more compact:
struct Derived1 : Base
{
Derived1() : Base(theFlag(this)) {}
};
Then in the header:
template <typename T>
bool theFlag(T*)
{
if (typeid(T) == typeid(Derived1)) return true;
if (typeid(T) == typeid(Derived2)) return false;
if (typeid(T) == typeid(Derived3)) return true;
throw std::runtime_error("No theFlag is given for this type");
}
If you are married to the compile-time check, the best you could do is to introduce a bit of duplication:
template <typename T>
bool theFlag(T*)
{
static_assert(
std::is_same<T, Derived1>::value ||
std::is_same<T, Derived2>::value ||
std::is_same<T, Derived3>::value,
"No theFlag is given for this type"
);
if (typeid(T) == typeid(Derived1)) return true;
if (typeid(T) == typeid(Derived2)) return false;
if (typeid(T) == typeid(Derived3)) return true;
}
This basically relies on SFINAE - the compiler would not be able to find an overload for theFlag
if you called it with an unsupported argument, essentially.