【发布时间】:2014-03-01 07:49:45
【问题描述】:
我正在尝试检测一个类是否具有特定功能(特别是shared_from_this(),它继承自std::enable_shared_from_this<Some Unknown Class>)。为了让事情变得更复杂,我需要知道它是否有这个功能,即使它是从远处的基类继承的,或者是使用受保护的访问继承的。
我查看了其他问题,例如 this one,但提供的方法不适用于检测受保护的成员函数。
我目前使用的方法如下:
template <class T>
struct shared_from_this_wrapper : public T
{
template <class U>
static auto check( U const & t ) -> decltype( t.shared_from_this(), std::true_type() );
static auto check( ... ) -> decltype( std::false_type() );
};
template<class T>
struct has_shared_from_this : decltype(shared_from_this_wrapper<T>::check(std::declval<shared_from_this_wrapper<T>>()))
{ };
我当前解决方案的缺陷是它不适用于声明为final 的类。所以我在寻找一个满足的成员函数测试解决方案:
- 使用声明为
final的类 - 使用受保护的成员函数
- 使用继承
- 不需要知道函数的返回类型
- 在 gcc、clang 和 MSVC 2013 下编译(最后一个可能限制过于花哨的 SFINAE)
编辑:我有一个可行的解决方案,但需要与帮助程序类成为朋友,这也不是一个理想的解决方案,但目前可能是一种解决方法(因为它满足所有要求):
struct access
{
template <class T>
static auto shared_from_this( T const & t ) -> decltype( t.shared_from_this() );
};
template <class U>
static auto check( U const & t ) -> decltype( access::shared_from_this(t), std::true_type() );
static auto check( ... ) -> decltype( std::false_type() );
template<class T>
struct has_shared_from_this2 : decltype(check(std::declval<T>()))
{ };
struct A : std::enable_shared_from_this<A> {};
struct B : protected A { friend class access; };
另一个编辑:类的示例以及检查 shared_from_this 之类的存在的类型特征应该返回什么:
struct A : std::enable_shared_from_this<A> {}; // should return true
struct B final : protected A {}; // should return true
struct C : A {}; // should return true
struct D {}; // should return false
我应该提到,我检测这个函数是否存在的最终目标是确定它的返回类型,以便找出std::enable_shared_from_this 模板化的类型。从std::enable_shared_from_this<T>继承给你std::shared_ptr<T> shared_from_this(),而T最终是我需要弄清楚的。这是正确序列化从std::enable_shared_from_this 继承的类型所必需的。
编辑第 3 部分:编辑:
这是为序列化库cereal 完成的,因此我对用户想要如何设计他们的类的控制为零。我希望能够序列化从std::enable_shared_from_this 派生的任何用户类型,其中包括将其类声明为最终类或在此过程中使用受保护继承的用户。任何需要干预被检查的实际类型的解决方案都不是有效的解决方案。
【问题讨论】:
-
这可能有帮助,也可能没有帮助:bloglitb.blogspot.ca/2010/07/…
-
我有一个通用实现,我可以检查它是否有效,但是,可以肯定的是,我需要一个具有此方法并展示所有要求 (1-4) 的类的原型示例才能工作与。
-
私有访问黑客的问题在于它需要知道返回类型 - 请参阅
struct Af { typedef void(A::*type)(); };行。在我描述的情况下,shared_from_this的返回类型未知。 -
我添加了一些结构示例以及这种类型特征的预期行为应该是什么。
-
如果它是最终类并且受到保护,你在乎吗?您无法访问该方法,句号。
标签: c++ c++11 final template-meta-programming sfinae