【发布时间】:2014-04-04 22:17:44
【问题描述】:
在 C++ 中,如果类具有命名字段、typedef 或方法,则在编译时可以使用 SFINAE 技巧。
我的问题是:我们也可以以某种方式查询方法是否可访问吗?就像区分私有方法和公共方法一样。
例如,如果我有一个从 std::vector 私下继承的类,例如 class T : private std::vector<int> { ... };,我不想检测它的 begin 方法,因为它不可公开访问。
当搜索 arround 时,我只获得检测方法的代码,与可见性无关......我得到的最接近的 was this 解决了继承的方法,但尚不清楚它如何与可见性交互。显然我可以测试,但我担心编译器特定的行为,因为我正在开发一个关于旧 Microsoft 编译器的项目:\
编辑 / 澄清:says here C++ 标准改变了它对这个问题的看法:对于 C++03,任何可见或不可见的成员都是可替代的,但由于 C++11 仅可见成员是。这是正确的吗?
我用下面的代码做了一些测试,它检测到value_type typedef。我不确定标准是怎么说的,但我用不同的编译器编译,结果如下:
- gcc : 4.4
true| 4.5true| 4.6true| 4.7true| 4.8false| 4.9 之前的false - Clang : 3.3
fail - icc : 13
true - msvc : 2005
true| 2010true| 2012true
代码如下:
#include <vector>
typedef char yes;
typedef int no;
template<class T> struct has_value_type {
template<class U> static yes test(typename U::value_type*);
template<class U> static no test(...);
static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};
class C : private std::vector<int> { };
int main() {
return has_value_type<C>::value;
}
【问题讨论】:
-
如果对存在的方法的 sfinae 检查成功,也应该意味着该方法是公共的(否则在 sfinae 检查期间调用它会导致 sfinae 失败),不是吗?
-
这里有一些你可以用来测试它的东西:coliru.stacked-crooked.com/a/630e969edc491662
-
我的 This answer 可能会有所帮助。如果由于某种原因无法调用该函数,则检查报告为 false。 Pre C++11,它认为这是不可能的。
-
访问检查在替换期间完成,但仅从 C++11 开始。 C++03 明确表示未完成访问检查。因此,您的示例将无法按 C++03 规则编译并在 C++11 中正确报告(即返回
false)。 This way 适用于这两种标准,也应该在旧编译器上编译,但遗憾的是它没有告诉我们关于value_type的可见性。你不能两者兼得。
标签: c++ visibility sfinae