访问条件 class 成员的方法仅在被调用时不编译

method, that accesses a conditional class member, does not compile only when being invoked

我写了下面的 class,它有一个条件成员 _sworksOnlyForString 访问成员的方法 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;
}

以下代码与名称无关,因此编译器会发现错误。

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();

所以只有在实例化函数时才会进行全面检查。

实例化 class 不会实例化每个方法。