gpt4 book ai didi

c++ - 实例化点后 ADL 未找到最佳匹配。这是UB吗?

转载 作者:太空狗 更新时间:2023-10-29 21:42:16 25 4
gpt4 key购买 nike

考虑以下代码,其中 f 的重载位置导致了一些非直观的行为。代码在 Clang 3.4.1 和 gcc 4.8 中编译时没有警告。

template<typename T>
struct A
{
static const int value = sizeof(f(T()));
};

struct B
{
};

struct D : B
{
};

char f(B);

// instantiates A<D>, unqualified name lookup finds f(B) via ADL
static_assert(A<D>::value == sizeof(f(B())), ""); // passes

long f(D); // but wait, f(D) would be a better match!

// A<D> is already instantiated, f(D) is not found
static_assert(A<D>::value == sizeof(f(B())), ""); // passes

C++11 标准建议上述代码调用未定义的行为:

[temp.dep.candidate]

For a function call that depends on a template parameter, the candidate functions are found using the usual lookup rules except that:

  • For the part of the lookup using unqualified name lookup or qualified name lookup, only function declarations from the template definition context are found.
  • For the part of the lookup using associated namespaces, only function declarations found in either the template definition context or the template instantiation context are found.

If the function name is an unqualified-id and the call would be ill-formed or would find a better match had the lookup within the associated namespaces considered all the function declarations with external linkage introduced in those namespaces in all translation units, not just considering those declarations found in the template definition and template instantiation contexts, then the program has undefined behavior.

上面的代码是否调用了这个特定的未定义行为?是否可以预期高质量的实现会报告警告?

最佳答案

Does the above code invoke this specific undefined behaviour?

是的。 [温度点]/7:

The instantiation context of an expression that depends on the template arguments is the set of declarations with external linkage declared prior to the point of instantiation of the template specialization in the same translation unit.

实例化点就在第一个 static_assert 之后-声明:

For […] a specialization for a […] static data member of a class template, if the specialization is implicitly instantiated because it is referenced from within another template specialization […]. Otherwise, the point of instantiation for such a specialization immediately follows the namespace scope declaration or definition that refers to the specialization.

因此,如果我们考虑第二个函数声明,确实会有更好的匹配 - 但我们不能,因为它是在 A<D>::value 的实例化点之后声明的。 .根据您引用的规则,代码会引发未定义的行为。
该规则基本上是将 ODR 扩展到模板中的相关名称查找。

Could a high-quality implementation be expected to report a warning?

我不会。还要考虑未定义的行为可以追溯到编译时;如果代码引发 UB,则允许但不要求编译器发出警告或错误消息。不要指望编译器总是指出非法代码。

关于c++ - 实例化点后 ADL 未找到最佳匹配。这是UB吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26790855/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com