C++模板来检查友元函数的存在
C++ template to check existence of friend function
我正在努力让以下代码发挥作用。这打印出";无setAttr";这感觉出乎意料。
基本上,我在Parent类中有一个方法,它创建一个子类的实例,并检查给定类型是否有特定的方法。当我公开方法(setAttr(((时,这是有效的,但不适用于友元函数。
我知道这可能看起来有点奇怪,使用一些遗留代码,我试图解决的用例是隐藏一个特定的方法(setAttr(((,一旦创建,它应该只能从负责生成子类实例的基类访问
template <typename, typename = void_t<>>
struct has_set_attr_method {
static constexpr bool value = false;
};
template <typename T>
struct has_set_attr_method<T, void_t<decltype(std::declval<T>().setAttr())>> {
static constexpr bool value = true;
};
struct Parent {
public:
template<typename T>
static void create() {
auto obj = T::create();
if constexpr(has_set_attr_method<T>::value) {
cout << "has setAttr" << endl;
obj.toString();
} else {
cout << "no setAttr" << endl;
}
}
};
struct Child : public Parent {
public:
friend class Parent;
static auto create() {
return Child();
}
private:
void setAttr(int x) {
}
};
int main(int argc, char const *argv[]) {
Parent::create<Child>();
return 0;
}
您的代码中有一些错误:
首先,您正在检查一个没有parms的方法,但您希望检查void setAttr(int x)
。如果您想用int
检查方法,您的测试必须类似于:decltype(std::declval<T>().setAttr(1)
(请参阅此处的附加int参数!(
如果您这样做,我们将运行一个gcc错误!它抱怨对模板声明中的私有函数的调用。由于SFINAE的确切意思是,如果我们在模板声明中有错误,我们不想出现错误,我认为这是一个gcc错误。clang编译没有任何问题。
BTW:这个bug已经在这里讨论过了:模板替换和SFINAE中的私有成员访问,此处:https://code-examples.net/en/q/25ea9ff
现在也是一份错误报告:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96204
可以,但结果仍然是永久返回false
。
原因:我们只是不在当前类型的上下文中进行检查,所以friend
没有效果!
解决方案:在正确的上下文中进行检查!只需将检查模板放在当前类的上下文中即可。
所以完整的代码示例(只使用clang,因为gcc抱怨模板中的私有声明感觉不对!(
struct Parent {
template <typename, typename = void_t<>>
struct has_set_attr_method {
static constexpr bool value = false;
};
template <typename T>
struct has_set_attr_method<T, void_t<decltype(std::declval<T>().setAttr(1))>> {
static constexpr bool value = true;
};
public:
template<typename T>
static void create() {
auto obj = T::create();
if constexpr(has_set_attr_method<T>::value) {
cout << "has setAttr" << endl;
} else {
cout << "no setAttr" << endl;
}
}
};
struct Child : public Parent {
public:
//friend class Parent;
static auto create() {
return Child();
}
private:
void setAttr(int x) {
}
};
int main(int argc, char const *argv[]) {
Parent::create<Child>();
return 0;
}
- C++模板来检查友元函数的存在
- C++quit()函数中可能存在作用域问题
- g++ 说函数不存在,即使包含正确的标头
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 根据某个函数是否存在启用模板
- 在 boost::variant 中类 holden 的复制构造函数存在问题
- 未定义的引用(但 nm 表示该函数存在)
- C++ 默认构造函数在移动和复制构造函数存在时不随"using"继承
- template_back和move赋值构造函数存在问题
- 基于方法或自由函数存在的模板构造函数解析
- 强制非类函数存在
- C++11/14:如果函数存在,则对其进行包装
- 递归函数存在out_of_range异常
- 匹配成员函数存在和签名:参数
- 未解析的外部符号错误,即使函数存在char*
- 在Qt创建者中推广QWidget,构造函数存在问题
- Boost MPL:只在(成员)函数存在时调用它
- 使用类而不是结构和构造函数存在问题
- Async_Read函数存在问题