gpt4 book ai didi

c++ - 检查成员是否存在,可能在基类中,C++11 版本

转载 作者:IT老高 更新时间:2023-10-28 12:44:56 26 4
gpt4 key购买 nike

https://stackoverflow.com/a/1967183/134841 ,提供了一种解决方案,用于静态检查成员是否存在,可能在某个类型的子类中:

template <typename Type> 
class has_resize_method
{
class yes { char m;};
class no { yes m[2];};
struct BaseMixin
{
void resize(int){}
};
struct Base : public Type, public BaseMixin {};
template <typename T, T t> class Helper{};
template <typename U>
static no deduce(U*, Helper<void (BaseMixin::*)(), &U::foo>* = 0);
static yes deduce(...);
public:
static const bool result = sizeof(yes) == sizeof(deduce((Base*)(0)));
};

但是,它不适用于 C++11 final 类,因为它继承自被测类,而 final 阻止了这一点。

OTOH,这个:

template <typename C>
struct has_reserve_method {
private:
struct No {};
struct Yes { No no[2]; };
template <typename T, typename I, void(T::*)(I) > struct sfinae {};
template <typename T> static No check( ... );
template <typename T> static Yes check( sfinae<T,int, &T::reserve> * );
template <typename T> static Yes check( sfinae<T,size_t,&T::reserve> * );
public:
static const bool value = sizeof( check<C>(0) ) == sizeof( Yes ) ;
};

在基类中找不到 reserve(int/size_t) 方法。

这个元函数的实现是否在 T 的基类中找到 reserved() 并且如果 T 仍然可以工作最终

最佳答案

实际上,由于 decltype 和后期返回绑定(bind)机制,C++11 中的事情变得容易多了。

现在,使用方法来测试它更简单:

// Culled by SFINAE if reserve does not exist or is not accessible
template <typename T>
constexpr auto has_reserve_method(T& t) -> decltype(t.reserve(0), bool()) {
return true;
}

// Used as fallback when SFINAE culls the template method
constexpr bool has_reserve_method(...) { return false; }

然后你可以在一个类中使用它,例如:

template <typename T, bool b>
struct Reserver {
static void apply(T& t, size_t n) { t.reserve(n); }
};

template <typename T>
struct Reserver <T, false> {
static void apply(T& t, size_t n) {}
};

你会这样使用它:

template <typename T>
bool reserve(T& t, size_t n) {
Reserver<T, has_reserve_method(t)>::apply(t, n);
return has_reserve_method(t);
}

或者你可以选择一个enable_if方法:

template <typename T>
auto reserve(T& t, size_t n) -> typename std::enable_if<has_reserve_method(t), bool>::type {
t.reserve(n);
return true;
}

template <typename T>
auto reserve(T& t, size_t n) -> typename std::enable_if<not has_reserve_method(t), bool>::type {
return false;
}

请注意,这种切换东西实际上并不那么容易。一般来说,当只存在 SFINAE 时会容易得多——并且您只想enable_if 一种方法而不提供任何回退:

template <typename T>
auto reserve(T& t, size_t n) -> decltype(t.reserve(n), void()) {
t.reserve(n);
}

如果替换失败,则从可能的重载列表中删除此方法。

注意:由于 ,(逗号运算符)的语义,您可以在 decltype 中链接多个表达式,并且只有最后一个实际决定类型。方便检查多个操作。

关于c++ - 检查成员是否存在,可能在基类中,C++11 版本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9530928/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com