c++ - 递归 enable_if 和类型转换

标签 c++ metaprogramming c++14 template-meta-programming sfinae

我想将相同数字的指针从 typename U 添加到 typename T,例如当 T = int***U = int*,结果为int****。所以,我写了以下内容:

#include <type_traits>

template <typename T, typename U,
          typename std::enable_if_t<std::is_pointer<U>::value>* = nullptr>
auto addPointer(T, U)
    -> decltype(addPointer(std::declval<std::add_pointer_t<T>>(),
                           std::declval<std::remove_pointer_t<U>>()));

template <typename T, typename U,
          typename std::enable_if_t<!std::is_pointer<U>::value>* = nullptr>
auto addPointer(T, U) -> T;

int main()
{
    using t =
        decltype(addPointer(std::declval<int***>(), std::declval<int*>()));
}

我在 Linux clang 3.7 上得到以下信息:

$ clang++ -std=c++14 -stdlib=libc++ -lc++abi -Wall -Wextra a.cpp 
a.cpp:16:18: error: no matching function for call to 'addPointer'
        decltype(addPointer(std::declval<int***>(), std::declval<int*>()));
                 ^~~~~~~~~~
a.cpp:5:6: note: candidate template ignored: substitution failure [with T = int ***, U =
      int *, $2 = nullptr]: call to function 'addPointer' that is neither visible in the
      template definition nor found by argument-dependent lookup
auto addPointer(T, U)
     ^
/usr/bin/../include/c++/v1/type_traits:244:78: note: candidate template ignored: disabled
      by 'enable_if' [with T = int ***, U = int *]
  ...<bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp, _Tp>::type;
                                                                         ^
1 error generated.

为什么会出现错误?

最佳答案

当我们处理标量时,ADL 不会在全局命名空间中查找。这样不仅无法找到后备重载,而且无法在 trailing-return-type 中引用您当前定义的重载。

使用 C++14,有一个更好的解决方案可以解决您的问题:

template <typename T>
T addPointer(T, ...);

template <typename T, typename U>
auto addPointer(T t, U* u) {return addPointer(&t, *u);}

Demo .

关于c++ - 递归 enable_if 和类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34071501/

相关文章:

c++ - 知道 QObject 名称是否已更改的最佳方法是什么

c++ - 如果遇到错误,如何重复代码?

java - 注释是 Java 中的某种 DSL 吗?

gcc - boost::variant 与多态性,clang 和 gcc 的性能结果非常不同

c++ - 找出特定整数有多少个二进制数字

c++ - 无法指定 vector 的初始大小

Java动态方法创建

java - Pluggable Annotation Processor API 可以检索源代码注释吗?

c++ - 为什么所有 C++ 编译器都会因为这段代码而崩溃或挂起?

c++ - 模板参数模棱两可/推导了参数的冲突类型