метод, который обращается к условному члену класса, не компилируется только при вызове - PullRequest
0 голосов
/ 25 октября 2018

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

0 голосов
/ 25 октября 2018

Следующий код не зависит от имени, поэтому ошибка спота компилятора.

void checkUnconditionalMember()
{
    std::cout<<_i.size();
}

In

std::conditional_t<isString, std::string, int> _s;

void worksOnlyForString()
{
    std::cout << _s.size();
}
  • _s зависит от имени (зависит от isString).
  • и т. Д. Для std::cout << _s.size();.

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

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

...