給定一個(降低)實現的detection idiom我們可以使用檢測成語來檢查一個類是否具有特定簽名的成員函數?
namespace type_traits
{
template<typename... Ts>
using void_t = void;
namespace detail
{
template<typename, template<typename...> class, typename...>
struct is_detected : std::false_type {};
template<template<class...> class Operation, typename... Arguments>
struct is_detected<void_t<Operation<Arguments...>>, Operation, Arguments...> : std::true_type {};
}
template<template<class...> class Operation, typename... Arguments>
using is_detected = detail::is_detected<void_t<>, Operation, Arguments...>;
template<template<class...> class Operation, typename... Arguments>
constexpr bool is_detected_v = detail::is_detected<void_t<>, Operation, Arguments...>::value;
}
,我們可以很容易地檢查,如果一個類foo
包含一個成員函數bar
struct foo {
int const& bar(int&&) { return 0; }
};
template<class T>
using bar_t = decltype(std::declval<T>().bar(0));
int main()
{
static_assert(type_traits::is_detected_v<bar_t, foo>, "not detected");
return 0;
}
然而,正如你可以看到,我們無法檢測foo::bar
參數類型是int&&
。檢測成功,原因0
可以傳遞給foo::bar
。我知道有很多選項可以檢查(成員)函數的確切簽名。但我想知道,如果可以修改此檢測工具包以檢測foo::bar
的參數類型恰好是int&&
。
[我創建這個例子中的一個live demo]
如果唯一的未知部分是返回類型,這很簡單。你是否也想覆蓋多個參數,你只需要精確地指定一些參數?那成員函數的cv-和ref-qualifiers怎麼樣? – dyp
這樣的事情? http://coliru.stacked-crooked.com/a/38ffdc13080301c6 – dyp
@dyp目前,'is_detected_v'會檢測'T'是否有任何*成員函數'bar',它接受'int'。在第一步中,我想添加一些'is_detected_exact'來檢測'T'是否有一個成員函數'bar',它的參數類型*完全是*'int'或*完全*'int &&'或*完全* 'int const&'等等。在第二步中,我想驗證一個確切的返回類型,但我想這很容易,因爲'bar_t'就是返回類型(只要decltype(...)中的表達式... )'是格式良好的)。 –
0xbadf00d