2017-03-27 1 views
0

큰 코드베이스를 clang (g ++ 및 intel C++로 빌드)에 이식합니다. 다음 스 니펫과 유사한 코드가 컴파일되어 g++ 4.8 - 6.2에서 작동하지만 clang 3.8 and 3.9으로 컴파일되지 않습니다. MinOp해야한다 (AFAICT)의 두 번째 호출 ("! 나 한테 전화하지 마세요") 기본 클래스의 전문화를 얻을 수 있지만, 그 소리는 버전 최소 성병을 :: 인스턴스화를 시도하고 실패하면 그enable_if를 사용하여 기본 클래스의 반환 유형을 전문화합니다.

#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)가없고 "전화하지 마!" 전문화는 MinOp 클래스 clang works too에 직접 있습니다.

이 using 문을 사용하면 기본 클래스에서 특수화를 가져올 수 있습니까?

이것은 나에게 매우 많은 가치가없는 기계류가 많은 것처럼 보입니다 (물론 이것은 거의 무의미한 점으로 단순화되었지만). 더 나은 아이디어?

+0

요구 사항을 나열하여 도와주세요. 고려해야 할 세 가지 조건이 있습니까? 두 가지 기본 유형, 기본 유형의 두 가지 벡터 및 비 기본 유형의 두 가지 벡터? –

+0

나를 위해 clang과 버그 인 것 같습니다. – Jarod42

+0

@RichardHodges : 내 코드가 아니지만 내가 이해할 수있는 요구 사항은 다음과 같습니다. 1. 기본 (float, double) 및 비 기본 (complex, Vector, Tensor 등 수레, 복식, 벡터 벡터 , 등). 2. 우리는 여러 작업 (min, max, assign, sum 등)을 가지고 있습니다. 모든 작업이 모든 유형에서 의미가있는 것은 아니지만 컴파일 또는 링크 시간이 아닌 런타임 오류로이 작업을 처리하기를 원합니다. 기본 클래스는 여러 작업에 의해 공유되며 이러한 작업을 지원하지 않는 여러 유형을 나열합니다. 그 파생 된 각각의 전문 분야를 복사 할 수 ... –

답변

0

는 동료가 내 질문에 SFINAE not working on llvm/clang

의 중복 지적 I 표준에 따라 "오른쪽"일을하고 그 소리 결론이 정확하다고 생각합니다. 요하네스 SCHAUB에서 - litb의 대답 : 그것은 파생의 멤버 함수 템플릿과 동일한 이름과 매개 변수를 가지고 있기 때문에 C++ 11 (상속 된 함수 템플릿의 사용 선언의

7.3.3 P15는 무시됩니다 클래스)

다른 컴파일러는 아마 "올바른"것이어야합니다. 이것이 표준의 결함으로보고되었는지는 알 수 없습니다.

해결 방법에는 모든 전문화를 기본 클래스에 넣거나 전문화 중 하나의 인수 유형 중 하나를 수정하는 것이 포함됩니다.

관련 문제