4

問題はここから来ました- もう少し一般的な問題を解決するアプローチを作成したかったのです。例を考えてみましょう:

#include <utility>

template<class T, std::size_t>
using deduced = T;

template<std::size_t N, class = std::make_index_sequence<N>>
struct Foo;

template<std::size_t N, std::size_t... Is>
struct Foo<N, std::index_sequence<Is...>>{
    template <class... Args>
    void Bar(deduced<Args, Is>...)
    {  }
};

int main() {
   Foo<3> myfoo;
   myfoo.Bar(true, 2.0f, 3); // OK
   //myfoo.Bar(1, 2, 3, 4); // error
}

clang ではコードのコンパイルに問題はありませんが、gcc では次のエラーが表示されます。

prog.cc: In function 'int main()':
prog.cc:18:27: error: no matching function for call to 'Foo<3ul>::Bar(bool, float, int)'
    myfoo.Bar(true, 2.0f, 3); // valid
                           ^
prog.cc:12:10: note: candidate: template<class ... Args> void Foo<N, std::integer_sequence<long unsigned int, Is ...> >::Bar(deduced<Args, Is>...) [with Args = {Args ...}; long unsigned int N = 3ul; long unsigned int ...Is = {0ul, 1ul, 2ul}]
     void Bar(deduced<Args, Is>...)
          ^~~
prog.cc:12:10: note:   template argument deduction/substitution failed:
prog.cc:18: confused by earlier errors, bailing out

【ライブデモ】

私を混乱させているのは、同じエイリアスを使用している場合、gcc の推論に問題はありませんが、外部パラメーター パックが関与していない場合です。

void Bar(deduced<Args, 0>...)

問題は、外部および内部クラスのパラメーター パックをこの形式のエイリアスと組み合わせて、コンパイラーにテンプレート パラメーターの 1 つを推測させることは合法ですか、それとも gcc のバグですか?

編集(ボグダンのコメントに基づく)

このコードはMSVC(2017 RC)にも問題を引き起こしますが、EDGコンパイラではこの形で動作し、icc(バージョン16と17)でも問題なくコードを扱えるようです。また、エイリアスの代わりにクラスを使用した同様のコード ( bogdan によるいくつかの場所での推定コンテキストとも見なされる) は、コンパイラにさらに多くの問題を引き起こすことにも注意してください - clang だけがこのバージョンをうまく処理しているようです(?)

4

0 に答える 0