テンプレートクラスのメンバ関数のオーバーロードを解決する際、g ++(5.2.1-23)とclang(3.8.0) )、-std=c++14
。enable_ifでのC++テンプレートのオーバーロード:g ++とclangとの動作が異なる
#include <iostream>
#include <type_traits>
struct Base
{
template <typename T>
auto a(T t) -> void {
std::cout<< "False\n";
}
};
template <bool Bool>
struct Derived : public Base
{
using Base::a;
template <typename T, bool B = Bool>
auto a(T t) -> std::enable_if_t<B, void>
{
std::cout<< "True\n";
}
};
int main()
{
Derived<true> d;
d.a(1); // fails with g++, prints "true" with clang
Derived<false> d2;
d2.a(1); // fails with clang++, prints "false" with g++
}
Derived<true>::a
への呼び出しは次のようなメッセージを持つG ++で失敗します。
test.cc: In function ‘int main()’:
test.cc:28:8: error: call of overloaded ‘a(int)’ is ambiguous
d.a(1);
^
test.cc:18:8: note: candidate: std::enable_if_t<B, void> Derived<Bool>::a(T) [with T = int; bool B = true; bool Bool = true; std::enable_if_t<B, void> = void]
auto a(T t) -> std::enable_if_t<B, void>
^
test.cc:7:8: note: candidate: void Base::a(T) [with T = int]
auto a(T t) -> void {
^
とDerived<false>::a
への呼び出しは次のようなメッセージと打ち鳴らす++で失敗します。
test.cc:32:6: error: no matching member function for call to 'a'
d2.a(1);
~~~^
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.2.1/../../../../include/c++/5.2.1/type_traits:2388:44: note: candidate template ignored: disabled by 'enable_if' [with T = int, B = false]
using enable_if_t = typename enable_if<_Cond, _Tp>::type;
^
私の推測では、ということですそれらはusing Base::a;
と異なって解釈され、clangでは考慮されませんが、g ++では(多分あまりにも)考慮されます。私は、Derived
にtrue
がパラメータとしてある場合、a()
の呼び出しがの実装に送出され、一方、パラメータがfalse
の場合、呼び出しはBase::a
にディスパッチされることが考えられます。
どちらも間違っていますか?誰が正しい?誰にバグレポートを提出すればよいですか?誰かが何が起こっているか説明できますか? 3.3.10/P3名と
おかげ
これは隠されていて、オーバーロードセットに含まれていないか、または表示されており、オーバーロードセットの一部です。 「時には隠されている」というのは意味をなさない。 –
だから私が正しく理解していれば、g ++は間違っているのです。なぜなら、 'using'との競合は考慮されるべきではなく、clangは間違っているからです。何も見つからなければ、' using'を見なければなりません。だから私は両方のコンパイラでバグレポートを提出する必要があります。 –
@VTolmer標準的な言い回しに基づいて、私はこれが当てはまると信じています。 – 101010