我有一个类,它是从第三方库中提供的类派生的。
在第三方库的两个版本之间,他们将一个类中的成员从私有提升为公共,但随后,他们弃用了一种访问成员的方法。示例:
// Old class
class A
{
public:
int &GetA() { return a;}
private:
int a;
};
// NewClass
class A
{
public:
int a;
};
我的代码使用A
的实例,但是我希望我的代码可以使用这两个版本,以防有人未更新库。
class B
{
public:
int & ReturnA() { return GetInnards(m_a);}
private:
A m_a;
// If m_a has a GetA member function call this:
template(typename aType)
int & GetInnards(aType &a) { return a.GetA(); }
// If m_a does not have an GetA() member function, call this:
template(typename aType)
int & GetInnards(aType &a) { return a.m_a; }
};
似乎我应该可以使用SFINAE,但是我缺少一些东西。
此外,我无法使用#ifdef
进行测试,因此我无法走这条路。我需要检测一种方法是否存在,或者某个成员是否为公共成员。
答案 0 :(得分:3)
嗯...给出了以下两个模板功能
template <typename A>
constexpr auto hasGetA (A const &)
-> decltype( std::declval<A>().GetA(), std::true_type{} );
template <typename ... Ts>
constexpr std::false_type hasGetA (Ts const & ...);
您可以编写您的方法
template <typename aType>
auto GetInnards (aType & a)
-> std::enable_if_t<true == decltype(hasGetA(a))::value, int &>
{ return a.GetA(); }
template <typename aType>
auto GetInnards (aType & a)
-> std::enable_if_t<false == decltype(hasGetA(a))::value, int &>
{ return a.a; }