C++ 我们可以使用检测习惯用法来检查类是否具有具有特定签名的成员函数吗?
考虑到 但是,正如您所看到的,我们无法检测到C++ 我们可以使用检测习惯用法来检查类是否具有具有特定签名的成员函数吗?,c++,templates,c++14,sfinae,typetraits,C++,Templates,C++14,Sfinae,Typetraits,考虑到 但是,正如您所看到的,我们无法检测到foo::bar的参数类型是int&。检测成功,因为0可以传递到foo::bar。我知道有很多选项可以检查(成员)函数的确切签名。但是我想知道,是否有可能修改这个检测工具包,以便检测foo::bar的参数类型正是int& [我已经创建了这个例子的一个例子。]在不改变你的类型特征的情况下,你可以这样做 template<typename T, T> struct helper {}; template<class T> usin
foo::bar
的参数类型是int&
。检测成功,因为0
可以传递到foo::bar
。我知道有很多选项可以检查(成员)函数的确切签名。但是我想知道,是否有可能修改这个检测工具包,以便检测foo::bar
的参数类型正是int&
[我已经创建了这个例子的一个例子。]在不改变你的类型特征的情况下,你可以这样做
template<typename T, T> struct helper {};
template<class T>
using bar_t = decltype(helper<const int& (T::*)(int&&), &T::bar>{});
template struct helper{};
模板
使用bar_t=decltype(helper{});
根据和的想法,我想出了
template<class T, typename... Arguments>
using bar_t = std::conditional_t<
true,
decltype(std::declval<T>().bar(std::declval<Arguments>()...)),
std::integral_constant<
decltype(std::declval<T>().bar(std::declval<Arguments>()...)) (T::*)(Arguments...),
&T::bar
>
>;
然而,虽然这个解决方案完全符合我的意图,但我讨厌为我想要检测的每个方法编写“如此复杂的代码”。我已经针对这个问题问了一个问题。我认为这不适用于检查常量限定符
decltype(std::declval<T>().bar(std::declval<Arguments>()...)) (T::*)(Arguments...)
decltype(std::declval().bar(std::declval()…)(T::*)(参数…)
始终生成非常量函数指针类型,而如果bar
标记为常量,则&T::bar
将生成常量函数指针
然后,尝试将常量指针类型转换为非常量指针类型以存储在
integral\u constant
中会失败。如果唯一未知的部分是返回类型,则很简单。如果只想精确地指定一些参数,是否还要覆盖多个参数?成员函数的cv和ref限定符呢?类似这样的东西@dyp当前检测到\u v
将检测T
是否有任何接受int
的成员函数bar
。在第一步中,我想添加某种类型的is\u detected\u exact
,它检测T
是否有一个成员函数bar
,其参数类型正是int
或正是int&
或正是int const&
,等等。在第二步中,我还想验证一个精确的返回类型,但我想这很容易,因为bar\u t
正是返回类型(只要decltype(…)
中的表达式格式正确)。@dyp是的,类似这样的东西!我们是否可以用函数式
标题的某些实用程序替换条形图辅助程序
?对于我的解决方案,您至少需要返回类型的类型推断。我不知道在
中有任何这样的工具。其中助手可以替换为整型常量
?可以简化为模板,使用bar\u t=typename std::integral\u constant:value\u type代码>
template<class T, typename... Arguments>
using bar_t = std::conditional_t<
true,
decltype(std::declval<T>().bar(std::declval<Arguments>()...)),
std::integral_constant<
decltype(std::declval<T>().bar(std::declval<Arguments>()...)) (T::*)(Arguments...),
&T::bar
>
>;
static_assert(type_traits::is_detected_v<bar_t, foo, int&&>, "not detected");
decltype(std::declval<T>().bar(std::declval<Arguments>()...)) (T::*)(Arguments...)