W.F*_*.F. 7 c++ private-members sfinae type-traits language-lawyer
在尝试创建特征以检查类字段是否公开可用时,我创建了一个代码:
#include <type_traits>
#include <utility>
template <class T, class = void>
struct does_not_have_foo: std::true_type {};
template <class T>
struct does_not_have_foo<T, decltype(std::declval<T>().foo, void())>: std::false_type {};
class Foo {
int foo;
};
int main() {
static_assert(does_not_have_foo<Foo>::value);
}
Run Code Online (Sandbox Code Playgroud)
但它似乎未能在[gcc]中编译([clang]似乎在这里更宽松)并出现错误:
prog.cc:8:56: error: 'int Foo::foo' is private within this context
Run Code Online (Sandbox Code Playgroud)
我为我的一些旧代码挖出了类似的东西,归结为以下内容:
template <class T>
auto does_not_have_foo(T t) -> decltype(t.foo, std::false_type()) {
return {};
}
std::true_type does_not_have_foo(...) { return {}; }
class Foo {
int foo;
};
int main() {
static_assert(decltype(does_not_have_foo(Foo{}))::value);
}
Run Code Online (Sandbox Code Playgroud)
它看起来像[gcc]和[clang]一样完成了它的工作.但是当我在寻找gcc失败的原因时,我发现了一个问题,即每次使用该类私有字段的尝试都是不正确的,因此即使是第二个代码也应该避免.我是在过度解释这个问题,还是第二个代码真的是语言滥用?
但它似乎未能在[gcc]中编译([clang]似乎在这里更宽松)
实际上gcc在这里更宽松.gcc bug 59002是一个元bug,它捕获了gcc在访问控制和模板方面的许多错误.对于gcc,在你的第一个场景中,访问Foo::foo
很好,即使它是私有的.在您的第二个略有不同的场景中,gcc正确拒绝私有访问.
does_not_have_foo
在第一个场景中正确实现,clang正确编译它.只是gcc错误地实现了访问检查.第二种实现同样正确.
归档时间: |
|
查看次数: |
149 次 |
最近记录: |