访问条件 class 成员的方法仅在被调用时不编译
method, that accesses a conditional class member, does not compile only when being invoked
我写了下面的 class,它有一个条件成员 _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;
}
以下代码与名称无关,因此编译器会发现错误。
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 不会实例化每个方法。
我写了下面的 class,它有一个条件成员 _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;
}
以下代码与名称无关,因此编译器会发现错误。
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 不会实例化每个方法。