我将大型代码库移植到clang(使用g ++和intel c ++构建)。类似于以下代码段的代码编译并适用于g++ 4.8 - 6.2,但无法使用clang 3.8 and 3.9进行编译。 MinOp的第二次调用应该(AFAICT)获得基类的特化("不要给我打电话!"),但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);
}
请注意,如果没有基类(MinOpBase),并且不打电话给我!&#34;专门化直接在MinOp类中clang works too。
使用using语句来引入基类的特化是否有效?
这对我来说就像一大堆机器并不是很有价值(虽然当然这已经简化到了无意义的程度)。更好的想法?
答案 0 :(得分:0)
一位同事指出我的问题是重复的 SFINAE not working on llvm/clang
我认为clang根据标准做“正确”事情的结论是正确的。来自Johannes Schaub - litb的回答:
7.3.3 p15 of C ++ 11(继承函数模板的using声明被忽略,因为它的名称和参数与 派生类的成员函数模板)
虽然其他编译器正在做可能应该是“正确”的事情。我不知道这是否已被报告为标准中的缺陷。
解决方法包括将所有特化项放入基类或修改其中一个特化项的参数类型。