将const限定符应用于模板参数

时间:2018-01-03 18:22:35

标签: c++ templates gcc clang const

考虑以下示例(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,用Clang编译的版本打印B

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

更新:正如@VTT指出的那样,即使as_const被删除,也会发现相同的差异。

1 个答案:

答案 0 :(得分:17)

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

委员会提出并讨论了这个问题:

  

目前尚不清楚以下是否格式良好:

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中,选择非const版本作为唯一可行的重载。

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

然而,

  

CWG的共识是参数和参数的cv限定必须匹配,因此原始示例应该被拒绝。

(注意上述问题)似乎表明gcc是对的,问题将得到解决,有利于其行为。