大きなコードベースをclang(g ++およびintel C++でビルド)に移植しています。次のスニペットに似たコードがコンパイルされ、g++ 4.8 - 6.2で動作しますが、clang 3.8 and 3.9でコンパイルできません。もしこと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);
}
注:MinOpの2番目の呼び出しは、(AFAICT)基底クラスの専門(「!私を呼び出さないでください」)を取得する必要がありますが、打ち鳴らすは:: STDをインスタンス化する分バージョンを試み、失敗しました基本クラス(MinOpBase)がなく、「私に電話しない!」専門化は直接MinOpクラスclang works tooにあります。
これは、usingステートメントを使用して、ベースクラスの特殊化を有効にしていますか?
これはあまり価値のない機械のようなものです(もちろんこれはほとんど無意味な点で簡素化されていますが)。より良いアイデア?
要件を記載してください。考慮すべき3つの条件がありますか? 2つの基本型、基本型の2つのベクトル、非基本型の2つのベクトル? –
私にとって不運なバグに見えます。 – Jarod42
@RichardHodges:私のコードではありませんが、私が理解している要件は次のとおりです。1.基本(フロート、ダブル)と非基本(複合、ベクトル、テンソルなど、浮動小数点数、 、など)。 2.複数の操作(最小、最大、割り当て、合計など)があります。すべての型ですべての操作が意味をなさないわけではありませんが、コンパイル時やリンク時ではなく実行時エラーで処理する必要があります。基本クラスはいくつかの操作で共有され、それらの操作をサポートしない多くの型をリストします。私はそれらの専門分野をそれぞれの派生語にコピーすることができます... –