以下のような条件で問題が発生しました。
#include <iostream>
#include <type_traits>
#define TRACE void operator()() const { std::cerr << "@" << __LINE__ << std::endl; }
template <class T>
struct check : std::true_type {};
template <class F, class T, class Check=void>
struct convert {
TRACE;// first case
};
template <class F, class T>
struct convert<F*, T, typename std::enable_if<(check<F>::value && check<T>::value), void>::type> {
TRACE; // second case
};
template <class T>
struct convert<int*, T, typename std::enable_if<(check<T>::value), void>::type> {
TRACE; // third case
};
それで
convert<int*, int> c;
c();
g++-4.5、g++-4.6、g++-4.7、clang++-3.1 (すべてオプション -std=c++0x を使用) であいまいなクラス テンプレートのインスタンス化が報告されます。
しかし、3番目のケースのチェックを次のように置き換えると
typename std::enable_if<(check<int>::value && check<T>::value), void>:type
その後、clang++-3.1 は正常に動作します。
コンパイラのバグですか、それとも標準ですか?