Метод, который обращается к условному члену класса, не компилируется только при вызове
Я написал следующий класс, который имеет условный член _s
а также worksOnlyForString
метод, который обращается к члену как std::string
, если worksOnlyForString
метод не вызывается, код компилируется, даже если член не std::string
,
Существует хорошо известное правило C++ - функция шаблона полностью компилируется только при использовании. Но в моем случае условный член вызывает такое поведение.
Вопрос в том, почему код компилируется.
#include <iostream>
#include <string>
#include <type_traits>
template<bool isString>
struct S
{
void worksAlways()
{
std::cout << _s;
}
// compiles for isString == false. (if not used)
// but why
void worksOnlyForString()
{
std::cout<<_s.size();
}
std::conditional_t<isString, std::string, int> _s;
#if 0
//this part does not compile and it is expected and ok
void checkUnconditionalMember()
{
std::cout<<_i.size();
}
int _i;
#endif
};
int main()
{
S<true> s;
s._s = "xxx";
s.worksOnlyForString(); // ok prints "3"
S<false> s1; // why does this line compile ?
s1._s = 99;
s1.worksAlways(); // ok prints "99"
return 0;
}
1 ответ
Решение
Следующий код не зависит от имени, поэтому ошибка компилятора.
void checkUnconditionalMember()
{
std::cout<<_i.size();
}
В
std::conditional_t<isString, std::string, int> _s;
void worksOnlyForString()
{
std::cout << _s.size();
}
_s
зависит от имени (зависит отisString
).- и так для
std::cout << _s.size();
,
Таким образом, полная проверка выполняется только при создании экземпляра функции.
Создание экземпляра класса не создает экземпляр каждого метода.