使用 enable_if 专注于基于 class 的 return 类型

using enable_if to specialize on return type from a base class

我正在将一个大型代码库移植到 clang(使用 g++ 和 intel c++ 构建)。类似于以下代码片段的代码可以在 g++ 4.8 - 6.2 but fails to compile with clang 3.8 and 3.9 上编译和运行。第二次调用 MinOp 应该 (AFAICT) 获得基础 class 专业化 ("Don't call me!"),但 clang 尝试实例化 std::min 版本并失败:

#include <algorithm>
#include <iostream>
#include <type_traits>

template <typename T> class Vector
{
public:
    Vector() : xyz{} {}
    Vector(T const &x, T const &y, T const &z) : xyz{y, y, z} {}
    Vector<T> min(Vector<T> const &v) { return Vector<T>(std::min(xyz[0], v.xyz[0]), std::min(xyz[1], v.xyz[1]), std::min(xyz[2], v.xyz[2])); }
    T xyz[3];
};

class MinOpBase
{
public:
    template <class T> typename std::enable_if<!std::is_fundamental<T>::value>::type
    operator()(Vector<T> &left, Vector<T> const &right) const { std::cout << "Don't call me!" << std::endl; }
};

class MinOp : public MinOpBase
{
public:
    template <typename T> void operator()(T &left, T const &right) const
    { left = std::min(left, right); }

    // Support component-wise min on vectors of fundamental types
    template <typename T> typename std::enable_if<std::is_fundamental<T>::value>::type
    operator() (Vector<T>  &left, Vector<T>  const &right) const
    {  left.min(right); }

    using MinOpBase::operator();
};

int main()
{
    Vector<double> v1, v2;
    Vector<Vector<double>> vv1, vv2;
    MinOp m;
    m(v1,v2);
    m(vv1,vv2);
}

注意如果没有基础class(MinOpBase),"Don't call me!"特化直接在MinOpclass,clang works too.

这种使用 using 语句从基础引入特化的方法是否有效?class

在我看来,这就像一大堆没有太大价值的机器(当然,这已经被简化到几乎毫无意义的地步)。更好的想法?

一位同事指出我的问题与 SFINAE not working on llvm/clang

我认为 clang 正在按照标准做 "right" 事情的结论是正确的。来自 Johannes Schaub - litb 的回答:

7.3.3 p15 of C++11 (the using declaration of the inherited function template is ignored because it has the same name and parameters as a member function template of the derived class)

虽然其他编译器正在做可能应该是 "right" 的事情。我不知道这是否已被报告为标准中的缺陷。

变通方法包括将所有特化放入基础 类 或修改其中一个特化的参数类型之一。