以下特征类用于检查通用 vector 是否具有operator[](int)
或operator()(int)
:
template<typename ...> using void_t = void;
template< typename, typename = void>
struct has_bracket_operator : public std::false_type {};
template<typename V>
struct has_bracket_operator<V, void_t<decltype(std::declval<V>()[int{}])> >
: public std::true_type{};
template<typename, typename = void>
struct has_parenthesis_operator : public std::false_type {};
template<typename V>
struct has_parenthesis_operator<V, void_t<decltype(std::declval<V>()(int{}))> >
: public std::true_type{};
看来compile well in gcc 5.1.0
另一方面,在最新的MSVC下载中(Microsoft Visual Studio Community 2015 RC版本14.0.22823.1 D14REL),我收到
has_parenthesis_operator
模板的编译器错误,内容为:而且,我发现以下版本最好完全不编译(请注意,使用
operator[](int{})
代替[int{}]
,并且括号类似):template<typename V>
struct has_bracket_operator<V, void_t<decltype(std::declval<V>().operator[](int{}))> >
: public std::true_type{};
//...
template<typename V>
struct has_parenthesis_operator<V, void_t<decltype(std::declval<V>().operator()(int{}))> >
: public std::true_type{};
错误消息是
问题:
void_t
)来解决?最佳答案
如@ T.C。所述,通过void_t<decltype(...)>
的上述方法需要expression SFINAE,在当前版本的MSVC 2015中不可用。
这是从here提取的SFINAE表达式的当前实现状态:
而且,这是使用传统SFINAE(灵感来自here)针对上述特征的一种老式解决方法:
template<typename C, typename Ret, typename... Args>
struct has_parenthesis_operator<C, Ret(Args...)>
{
private:
template<typename T>
static constexpr auto check(T*)
-> typename std::is_same<std::decay_t<decltype(std::declval<T>().operator()(std::declval<Args>()...))>, Ret>::type;
template<typename> static constexpr std::false_type check(...);
typedef decltype(check<C>(0)) type;
public:
static constexpr bool value = type::value;
};
例如可以用作
template<typename V
, typename = std::enable_if_t<has_bracket_operator<V, double(int)>::value>
auto get(V const& v, int i)
{
return v[i];
}
这将检查所传递的 vector 类型是否具有成员
double operator[](int)
,如果存在则称为成员(否则,可以使用括号运算符执行类似操作)。关于@Yakk的评论:我遇到了MSVC的
__if_exists
statement特殊功能,它似乎完成了与上述操作类似的任务。关于c++ - 用于检测成员函数的C++特征类:MSVC 2015 RC中的编译器错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30856989/