私が書いているプログラムでいくつかの不可解な SFINAE 問題が発生していたので、それを独立したサンプル プログラムにまとめました。
#include <type_traits>
struct Base { };
struct Derived : public Base { };
template<typename T>
struct From { };
template<typename T>
struct To {
template<typename U>
To(const From<U>& other) {
static_assert(std::is_convertible<U*, T*>::value, "error");
}
};
int main() {
From<Derived> a;
To<Base> b = a;
}
このプログラムは、エラーや警告なしでコンパイルされます。ただし、これは次のとおりです。
#include <type_traits>
struct Base { };
struct Derived : public Base { };
template<typename T>
struct From { };
template<typename T>
struct To {
template<typename U>
To(const From<typename std::enable_if<true, U>::type>& other) {
// this ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
static_assert(std::is_convertible<U*, T*>::value, "error");
}
};
int main() {
From<Derived> a;
To<Base> b = a;
}
次のエラーが発生します。
test.cpp: 関数内
int main()
:test.cpp:22:18: エラー: から
From<Base>
非スカラー型への変換がTo<Derived>
要求されました
これは、おそらく置換が失敗し、コンストラクターが表示されないためです。
SFINAE のやり方が間違っているのでしょうか、それともコンパイラのバグですか? WindowsでruvenvbのGCC 4.7.1を使用しています(std=c++11
違いがある場合)。