如何按类型启用受保护的方法
How to enable a protected method by type
我想在派生类中公开提供一个函数,只有当调用参数具有特殊标签时。我正在使用clang的C 14。
给出以下情况:
struct TagA {};
struct TagB {};
struct Base {
protected:
void handler(const std::shared_ptr<Base> &obj) {
...
}
};
目标是使handler
在派生类中可用,如果它们具有特殊标签,以允许派生对象的不同"类"。这样:
struct DerivedA : Base, TagA {
// This should only be available, if the obj argument for handler
// derives from TagA
// something like std::enable_if<std::is_base_of<TagA, ???>::value>
using Base::handler;
};
这将允许DerivedA
处理
struct HandledA : Base, TagA {
};
但不是
struct UnhandledA : Base, TagB {
};
尽管UnhandledA
从Base
继承,而handler
仅需要Base
。
如果我正确研究了您的问题,可以使用CRTP(工作版本(实现此目标:
#include <memory>
#include <type_traits>
struct TagA {};
struct TagB {};
template< typename tp_Derived > struct BaseCRTP;
struct Base
{
template< typename > friend
struct BaseCRTP;
private: void
handler_impl(const std::shared_ptr<Base> &) {}
};
template< typename tp_Derived >
struct BaseCRTP: public Base
{
public: void
handler(const std::shared_ptr<Base> & obj)
{
static_assert
(
::std::is_base_of< TagA, tp_Derived >::value
, ""handler" method can only be used in classes deriving from TagA"
);
return(handler_impl(obj));
}
};
struct DerivedA : BaseCRTP< DerivedA >, TagA
{};
struct DerivedB : BaseCRTP< DerivedB >, TagB
{};
int main()
{
DerivedA a; // OK
(void) a; // not used
auto pha(&DerivedA::handler); // OK
DerivedB b; // OK
(void) b; // not used
auto phb(&DerivedB::handler); // static_assertion failure
return 0;
}
另一种CRTP解决方案可能涉及Sfinae(std::enable_if<>
(,如下所示
#include <memory>
#include <type_traits>
struct TagA {};
struct TagB {};
template <typename Der>
struct Base
{
protected:
template <typename D = Der>
typename std::enable_if<std::is_base_of<TagA, D>::value>::type
handler (std::shared_ptr<Base> const &)
{ }
};
struct DerivedA : Base<DerivedA>, TagA
{ using Base::handler; };
struct DerivedB : Base<DerivedB>, TagB
{ using Base::handler; };
int main ()
{
DerivedA{}.handler(nullptr); // compile
DerivedB{}.handler(nullptr); // compilation error
}
避免使用处理程序的使用可能会像以下内容那样放松地阐明模板类型
DerivedB{}.handler<TagA>(nullptr); // now compile
您可以改进std::enable_if
测试,也强烈认为D
等于Der
template <typename D = Der>
typename std::enable_if< std::is_base_of<TagA, D>::value
&& std::is_same<D, Der>::value>::type
handler (std::shared_ptr<Base> const &)
{ }
相关文章:
- 覆盖作为另一个类的好友的虚拟受保护方法
- 无法在赋值运算符中访问基类的受保护方法
- 如何按类型启用受保护的方法
- 用受保护的继承指向基类方法
- 受保护的方法在 c++ 中继承时可以成为私有方法
- std::异步不能调用受保护的基类方法
- Boost单元测试夹具继承测试类,是否可以访问受保护的方法
- 在派生类中定义自定义返回类型的受保护方法
- 有什么方法可以在工会内部获得受保护的声明吗
- 通过此指针调用受保护的基类方法,该指针投射到派生类(C++)中的基类
- 访问受保护成员的公共方法
- C++:重写由另一个方法调用的受保护方法
- 这种使用虚拟受保护方法扩展库的方式是否安全
- 派生类是否可以访问作为内部类的好友的父类的受保护内部类的私有方法
- 为什么无法从模板方法访问此类自己的受保护成员?
- 从基类的静态模板方法中调用继承类的受保护 ctor 失败
- 在C++中为成员对象调用受保护的方法
- 通过 DllImport 在 C# 中调用 C 方法 - 尝试读取或写入受保护的内存
- 派生类中的反射工厂C++无法访问受保护的方法
- 使用关键字公开受保护的重载方法