Метод, который обращается к условному члену класса, не компилируется только при вызове

Я написал следующий класс, который имеет условный член _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();,

Таким образом, полная проверка выполняется только при создании экземпляра функции.

Создание экземпляра класса не создает экземпляр каждого метода.

Другие вопросы по тегам