採取下面的代碼,其特點是ADL相關GCC 4.7.2問題與表達SFINAE
- 依賴ADL爲特定行爲(
volume
) - 使用decltype用於返回類型和依託SFINAE丟棄額外重載
namespace Nature {
struct Plant {};
double volume(Plant){ return 3.14; }
}
namespace Industrial {
struct Plant {};
double volume(Plant) { return 100; }
}
namespace SoundEffects {
// A workaround for GCC, but why?
////template<class T> void volume();
template<class aSound>
auto mix(aSound& s) -> decltype(volume(s)*0.1)
{
return volume(s)*.1;
}
struct Samples {
Nature::Plant np;
Industrial::Plant ip;
};
inline double mix(const Samples& s) {
return mix(s.np) + mix(s.ip);
}
}
int main()
{
SoundEffects::Samples s;
assert(mix(s) == 100*.1 + 3.14*.1);
}
的代碼提交(不template<class T> void volume()
線),VS 2012和clang 3.5編譯成功,運行時間與預期一致。然而,GCC 4.7.2說:
template-function-overload.cpp: In substitution of 'template<class aSound> decltype ((volume(s) * 1.0000000000000001e-1)) SoundEffects::mix(aSound&) [with aSound = SoundEffects::Samples]':
template-function-overload.cpp:46:4: required from here
template-function-overload.cpp:23:9: error: 'volume' was not declared in this scope
template-function-overload.cpp:23:9: note: suggested alternatives:
template-function-overload.cpp:9:11: note: 'Nature::volume'
template-function-overload.cpp:14:11: note: 'Industrial::volume'
,具有額外template volume
線,所有三個編譯和運行正常。
因此,這裏顯然存在編譯器缺陷。我的問題是,哪個編譯器是有缺陷的?哪個C++標準被違反?
哪個版本的GCC?無法用4.8,4.9,5.1中的任何一個來重放 –