Причина вашей ошибки заключается в том, что if
s по сути являются конструкциями времени выполнения, в то время как шаблоны являются конструкциями времени компиляции.
Что это действительно означает, что после компиляции ваша функция шаблона будет выглядеть примерно так:
void MyClass::AddType(std::string value)
{
if(some_value_for_typeid(std::string) == some_value_for_typeid(bool))
{
b_val = value;
}
else if(some_value_for_typeid(std::string) == some_value_for_typeid(int))
{
i_val = value;
}
}
Давайте сделаем это еще яснее:
void MyClass::AddType(std::string value)
{
if(2 == 3)
{
b_val = value;
}
else if(2 == 5)
{
i_val = value;
}
}
Стандарт, если для необходимо , чтобы иметь возможность управлять своим телом, в случае, если условие когда-либо будетправда. Таким образом, это компилируется, и это терпит неудачу.
Что можно сделать с этим? Существует несколько вариантов.
Наиболее близким к вашему решению является использование нового C ++ 17 if constexpr
. Эта конструкция действует точно так же, как обычный if
, только то, что оценивается во время компиляции. Недостатком является то, что выражение должно быть возможным для оценки во время компиляции (оно должно быть выражением constexpr
), а operator==
для std::type_info
(вещь, возвращаемая typeid
) не является constexpr. Но есть std::is_same
, который выполняет сравнение типов в стиле constexpr:
template<typename T>
void MyClass::AddType(T value)
{
if constexpr (std::is_same<T, bool>::value) {
b_val = value;
} else if constexpr (std::is_same<T, bool>::value) {
i_val = value;
}
}
При компиляции, конструкция целого if уменьшится до b_val = value;
, i_val = value;
или ничего.
Другой вариант - просто перегружать функцию, просто определяя MyClass::AddType(bool);
и MyClass::AddType(int)
.
. Третий метод - это специализация шаблона . (что лично мне кажется не очень хорошей идеей в данном конкретном случае).