c++ - 访问条件类成员的方法仅在被调用时不编译

标签 c++ templates dependent-name

我编写了以下具有条件成员 _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(); .

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

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

关于c++ - 访问条件类成员的方法仅在被调用时不编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52990568/

相关文章:

c++ - 模板参数中的T&和T&&有什么区别?

c++ - static_assert 依赖于非类型模板参数(gcc 和 clang 的不同行为)

c++ - 构建后Eclipse将头文件复制到特定位置

c++ - 为什么这个结构不是标准布局?

C++ 模板继承方案

c++ - 在模板特化中使用非类型模板模板参数

c++ - 为什么必须在何处以及为什么要放置"template"和"typename"关键字?

c++ - 为什么必须在哪里放置 “template”和 “typename”关键字?

c++ - 在 C++ 中,我可以防止派生类被 friend 以外的类实例化吗?

c++ - 清理双向迭代器代码