如何在构造函数上正确使用std :: enable_if

时间:2018-03-14 20:20:36

标签: c++ template-meta-programming enable-if

这个问题结合了几段代码并且有点复杂,但我尝试尽可能减少它。

当使用lambda表达式作为输入时,我试图使用next_link := apex_json.get_varchar2('odata.nextLink');有条件地调用正确的构造函数作为模糊函数签名的结果,但是所述lambda表达式的参数可以隐式地相互转换。

这是尝试建立在以下问题的基础上:Here,但又有所不同,并侧重于std::enable_if值得另一个问题。我还提供Live Example,其中包含已注释掉的问题部分。

要检查仿函数的参数(和结果)类型,我有以下类:

std::enable_if

然后我尝试运行下面的代码,但template <typename T> struct function_traits : public function_traits<decltype(&T::operator())> {}; // For generic types, directly use the result of the signature of its 'operator()' template <typename ClassType, typename ReturnType, typename... Args> struct function_traits<ReturnType(ClassType::*)(Args...) const> // we specialize for pointers to member function { enum { num_args = sizeof...(Args) }; typedef ReturnType result_type; template <size_t N> struct arg { typedef typename std::tuple_element<N, std::tuple<Args...>>::type type; // the i-th argument is equivalent to the i-th tuple element of a tuple // composed of those arguments. }; }; 部分似乎不起作用,但我知道括号内的所有内容都(或应该)正如Live Example所示

std::enable_if

那我错过了什么?我正在以#5 here为例。

1 个答案:

答案 0 :(得分:2)

从属名称

typename function_traits<Lambda>::template arg<0>::type
                                  ^^^^^^^^

有关相关名称的详细信息以及何时需要templatetypename,请参阅this帖子。

enable_if

typename = std::enable_if_t<condition>

应该是

std::enable_if_t<condition>* = nullptr
正如@ Jarod42所提到的那样。这是因为构造函数否则将是相同的并且不能被重载。它们的默认值不同并不会改变这一事实。有关详细信息,请参阅this

将它放在一起是

template<typename Lambda, std::enable_if_t<std::is_same_v<typename function_traits<Lambda>::template arg<0>::type, a_type>>* = nullptr>
A(const Lambda&);

Live

旁注

function_traits无法使用重载或模板operator(),而是可以替换它

template<typename T, typename... Args>
using return_type = decltype(std::declval<T>()(std::declval<Args>()...));

template<typename T, typename... Args>
using mfp = decltype(static_cast<return_type<T, Args...>(T::*)(Args...) const>(&T::operator()));

template<typename Lambda, mfp<Lambda, a_type> = nullptr>
A(const Lambda&);

检查是否可以使用确切的参数调用callable而不进行转换。