推导依赖类型的静态成员函数的 return 值的正确语法
correct syntax for deducing return value of static member function of dependent type
我想不出推导依赖类型的静态成员函数的 return 值的正确语法。我已经尝试了十几种组合,包括使用 ::std::result_of 和 none,它们似乎都有效。这是看起来最有希望的变体(至少在非模板上下文中有效):
struct
t_In
{
};
struct
t_Out
{
static auto
Method(t_In &) -> t_Out
{
return(t_Out());
}
};
template<typename tp_Out, typename tp_In, typename tp_Enable = void> struct
t_Template;
template<typename tp_Out, typename tp_In> struct
t_Template
<
tp_Out
, tp_In
, typename ::std::enable_if
<
::std::is_same
<
decltype
(
::std::remove_cv // adding typename here makes Method look like type
<
typename ::std::remove_reference
<
tp_Out
>::type
>::type::Method(::std::declval<tp_In>()) // Err: does not evaluate to function ...
)
, tp_Out
>::value
>::type
>
{
};
编辑:编译器 VS2013,请注意我什至没有实例化任何东西,仅从这个模板弹出错误
您的一个问题是 std::declval
returns 一个右值引用,它不能绑定到像 t_In&
.
这样的非常量左值引用
一个相当干净的解决方案是使用 void_t
和 std::declval<tp_In&>
:
//standard void_t implementation
template <typename...> struct voider { using type = void; };
template <typename...Ts> using void_t = typename voider<Ts...>::type;
//primary template
template<typename tp_Out, typename tp_In, typename tp_Enable = void>
struct t_Template;
//for when tp_Out has a static member function called Method
//taking an lvalue reference to tp_In
template<typename tp_Out, typename tp_In>
struct t_Template
<tp_Out, tp_In, void_t<decltype(tp_Out::Method(std::declval<tp_In&>()))>>
{
};
tl;博士; VS2013 中的 type::StaticMemberFunctionName 语法在模板参数中使用时会被破坏,像 decltype(decltype(*&tp_Out::Method)(::std::declval())) 这样的奇特表达式甚至会导致内部编译器错误。
然而,这种语法在其他地方使用时仍然有效,所以我设法找到了一个解决方法:
template<typename tp_Out, typename tp_In> struct
t_MethodReturnValueDeducer
{
typedef decltype
(
::std::remove_cv
<
typename ::std::remove_reference
<
tp_Out
>::type
>::type::Method(::std::declval<tp_In &>())
) t_Deduced;
};
template<typename tp_Out, typename tp_In, typename tp_Enable = void> struct
t_Template;
template<typename tp_Out, typename tp_In> struct
t_Template
<
tp_Out
, tp_In
, typename ::std::enable_if
<
::std::is_same
<
typename t_MethodReturnValueDeducer<tp_Out, tp_In>::t_Deduced
, tp_Out
>::value
>::type
>
{
};
我希望这对仍在使用 VS2013 的人有所帮助...
我想不出推导依赖类型的静态成员函数的 return 值的正确语法。我已经尝试了十几种组合,包括使用 ::std::result_of 和 none,它们似乎都有效。这是看起来最有希望的变体(至少在非模板上下文中有效):
struct
t_In
{
};
struct
t_Out
{
static auto
Method(t_In &) -> t_Out
{
return(t_Out());
}
};
template<typename tp_Out, typename tp_In, typename tp_Enable = void> struct
t_Template;
template<typename tp_Out, typename tp_In> struct
t_Template
<
tp_Out
, tp_In
, typename ::std::enable_if
<
::std::is_same
<
decltype
(
::std::remove_cv // adding typename here makes Method look like type
<
typename ::std::remove_reference
<
tp_Out
>::type
>::type::Method(::std::declval<tp_In>()) // Err: does not evaluate to function ...
)
, tp_Out
>::value
>::type
>
{
};
编辑:编译器 VS2013,请注意我什至没有实例化任何东西,仅从这个模板弹出错误
您的一个问题是 std::declval
returns 一个右值引用,它不能绑定到像 t_In&
.
一个相当干净的解决方案是使用 void_t
和 std::declval<tp_In&>
:
//standard void_t implementation
template <typename...> struct voider { using type = void; };
template <typename...Ts> using void_t = typename voider<Ts...>::type;
//primary template
template<typename tp_Out, typename tp_In, typename tp_Enable = void>
struct t_Template;
//for when tp_Out has a static member function called Method
//taking an lvalue reference to tp_In
template<typename tp_Out, typename tp_In>
struct t_Template
<tp_Out, tp_In, void_t<decltype(tp_Out::Method(std::declval<tp_In&>()))>>
{
};
tl;博士; VS2013 中的 type::StaticMemberFunctionName 语法在模板参数中使用时会被破坏,像 decltype(decltype(*&tp_Out::Method)(::std::declval())) 这样的奇特表达式甚至会导致内部编译器错误。 然而,这种语法在其他地方使用时仍然有效,所以我设法找到了一个解决方法:
template<typename tp_Out, typename tp_In> struct
t_MethodReturnValueDeducer
{
typedef decltype
(
::std::remove_cv
<
typename ::std::remove_reference
<
tp_Out
>::type
>::type::Method(::std::declval<tp_In &>())
) t_Deduced;
};
template<typename tp_Out, typename tp_In, typename tp_Enable = void> struct
t_Template;
template<typename tp_Out, typename tp_In> struct
t_Template
<
tp_Out
, tp_In
, typename ::std::enable_if
<
::std::is_same
<
typename t_MethodReturnValueDeducer<tp_Out, tp_In>::t_Deduced
, tp_Out
>::value
>::type
>
{
};
我希望这对仍在使用 VS2013 的人有所帮助...