2017-10-23 7 views
2

私はC++ 11で書かれた科学的なコードに取り組んでいます。このコードの重要な操作は、3D配列で実行されます。そのような配列はまた、他の関数に多く渡されます。いくつかの新機能を実装しているうちに、テンプレートを使用して以下の問題が発生しました。コードはgcc 5.4(テスト済み7.2)でもコンパイルできますが、インテルC++コンパイラICC 16.0(18.0もテスト済み)ではコンパイルされません。コードが標準に準拠していないか、それらのコンパイラの1つが誤動作している場合。次のようにテンプレート関数の配列サイズとしてのConstexpr(GCC vs Intel)

最小のサンプルコードは、(実際に、それは3次元配列であろう)になります

class Constants { 
    static constexpr int value_ = 2; 

public:  
    static constexpr inline int V() { return value_; }  
}; 

typedef Constants CC; 

template<int N> 
class Terror {  
public: 
    template<class T> 
    void F(T (&a)[CC::V()]) {} 
}; 

int main() { 
    int array[CC::V()];  
    Terror<42> ter = Terror<42>();  
    ter.F(array); 
} 

Iはconstexprにより決定サイズの(3D)無地Cアレイを通過することではないことを知っています古典的なアプローチですが、必要に応じてこれを説明する理由があります。

私はC++ 11標準で読んでみましたが、問題に明確な(少なくとも私にとっては)説明が見つかりませんでした。

エラーICCが投げているが、このです:

main.cpp(15): error: no instance of function template "Terror<N>::F [with N=42]" matches the argument list 
      argument types are: (int [2]) 
      object type is: Terror<42> 
    ter.F(array); 
    ^
template_class.h(10): note: this candidate was rejected because at least one template argument could not be deduced 
    void F(T (&a)[CC::V()]) {} 
     ^

compilation aborted for main.cpp (code 2) 

興味深いことに、それは(3D-)はstd ::アレイ又はN/Tが存在しないされている2つのテンプレートの場合は、1つで動作します。

答えて

4

これはICCのバグです。

template<int N> 
class Terror {  
    static constexpr size_t M = CC::V(); 
public: 
    template<class T> 
    void F(T (&a)[M]) {} 
}; 

ICC 16と17の両方この変更にあなたのプログラムを受け入れる:

ありがたいことに、ちょうどTerror以内にその値を記憶している非常に単純な回避策があります。

+0

インテルは知っていますか?彼らはこれを修正する方法になっていますか? – SamVanDonut

+0

@SamVanDonut iccのバグレポートを送信する方法がわかりません。 – Barry

関連する問題