代码之家  ›  专栏  ›  技术社区  ›  vitaut

将常量限定符应用于模板参数时的不同编译器行为

  •  27
  • vitaut  · 技术社区  · 7 年前

    考虑以下示例( godbolt ):

    #include <iostream>
    
    template <typename T>
    const T *as_const(T *p) { return p; }
    
    void f() {}
    
    template <typename T>
    void g(T *) { std::cout << "A"; }
    
    template <typename T>
    void g(const T *) { std::cout << "B"; }
    
    int main() {
      g(as_const(&f));
    }
    

    GCC和Clang都可以编译它,但生成的可执行文件会产生不同的输出:使用GCC编译的版本会打印 A 还有那张用叮当声打印出来的 B .

    你能解释一下这种区别吗?

    使现代化 :正如@VTT所指出的,即使 as_const 已删除。

    1 回复  |  直到 7 年前
        1
  •  17
  •   Baum mit Augen    7 年前

    您似乎遇到了标准中尚未解决的缺陷。那么,“哪个编译器是对的?”目前还不完全清楚。

    该问题已提交委员会讨论:

    尚不清楚以下内容是否正确:

    void foo(){}
    
    template<class T>
    void deduce(const T*) { }
    
    int main() {
      deduce(foo);
    }
    

    实现在处理这个示例时会有所不同。

    看见 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1584 ,但提议的解决方案不是N4141或N4659的一部分。

    请注意,通常不能有指向 const 功能类型;如果您认为我引用的示例格式不正确,那么gcc是正确的。它确实拒绝了这个示例,并且在OP中,选择非常量版本作为唯一可行的重载。

    如果叮当声(哪个 claims to implement the proposed resolution )否则就对了,我不敢肯定。我想,一旦委员会用一些我们可以使用的规范性措辞解决了这个问题,我们就必须重新讨论这个问题。

    然而

    CWG的一致意见是,参数和参数的cv限定必须匹配,因此应拒绝原始示例。

    (上述问题的注释)似乎表明gcc是正确的,问题的解决将有利于其行为。