C++ 与ADL相关的GCC 4.7.2问题,带有SFINAE表达式

C++ 与ADL相关的GCC 4.7.2问题,带有SFINAE表达式,c++,templates,c++11,argument-dependent-lookup,C++,Templates,C++11,Argument Dependent Lookup,以下面的代码为例,其特征是 对特定行为的ADL依赖(卷) 使用decltype作为返回类型并依赖SFINAE丢弃额外的重载 名称空间性质{ 结构植物{}; 双卷(工厂){返回3.14;} } 名称空间工业{ 结构植物{}; 双卷(工厂){return 100;} } 命名空间声音效果{ //GCC的解决方案,但为什么? ////模板空隙体积(); 模板 自动混音(aSound&s)->decltype(音量)*0.1 { 退货数量*1; } 结构样本{ 性质:植物np; 工业:工厂ip; };

以下面的代码为例,其特征是

  • 对特定行为的ADL依赖(
  • 使用decltype作为返回类型并依赖SFINAE丢弃额外的重载
  • 名称空间性质{
    结构植物{};
    双卷(工厂){返回3.14;}
    }
    名称空间工业{
    结构植物{};
    双卷(工厂){return 100;}
    }
    命名空间声音效果{
    //GCC的解决方案,但为什么?
    ////模板空隙体积();
    模板
    自动混音(aSound&s)->decltype(音量)*0.1
    {
    退货数量*1;
    }
    结构样本{
    性质:植物np;
    工业:工厂ip;
    };
    内联双混合(常量样本和s){
    返料混合料(s.np)+混合料(s.ip);
    }
    }
    int main()
    {
    声音效果::样品;
    断言(混合=100*.1+3.14*.1);
    }
    
    所显示的代码(没有
    模板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-function-overload.cpp:替换“模板decltype((卷)*1.000000000000000 1E-1))SoundEffects::mix(aSound&)[带aSound=SoundEffects::Samples]:
    模板函数重载。cpp:46:4:此处为必填项
    模板函数重载。cpp:23:9:错误:“卷”未在此作用域中声明
    模板函数重载。cpp:23:9:注意:建议的备选方案:
    模板函数重载。cpp:9:11:注意:'Nature::volume'
    模板函数重载。cpp:14:11:注意:“Industrial::volume”
    
    有了额外的
    模板卷
    行,所有三个都可以正常编译和运行


    因此,这里显然存在编译器缺陷。我的问题是,哪个编译器是有缺陷的?哪一个C++标准被违反了?

    这是一个错误。下面是给出相同错误的代码示例:

    模板
    自动嗡嗡声(tx)->decltype(foo(x));
    无效嗡嗡声(int);
    int main(){
    buzz(5);//错误:“foo”未在此范围内声明
    }
    
    mix
    中,
    SoundEffects::mix
    的两个重载都通过ADL编译到候选重载集中(
    SoundEffects
    SoundEffects::Sample
    的关联命名空间)。评估函数模板重载的可行性。发生此错误的原因是无法通过纯非限定查找或样本的ADL将
    解析为合适的重载

    这应该通过的原因是,当查找失败时,应该发生替换失败(因为
    是依赖的),并且应该从重载解析中拒绝模板。这将使
    mix(const Sample&)
    成为唯一可以选择的可行重载。存在硬错误这一事实清楚地表明,此GCC版本的SFINAE实现存在错误

    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'