gpt4 book ai didi

c++ - 与条件 noexcept 和重载不一致

转载 作者:可可西里 更新时间:2023-11-01 17:53:21 26 4
gpt4 key购买 nike

我有一个与 this 非常相似的问题一个。

简而言之,我有一个 magic方法,即 noexcept如果另一种方法是 noexcept .

奇怪的是这个“另一个方法”有两个重载,编译器选择第二个重载来确定magic noexcept -性。

然而,当magic稍后调用,first 重载被调用,但是 noexcept -性 magic保持不变!

这是魔杖盒 link

据我了解:

  1. noexcept(magic(dummy2{}))电话
  2. noexcept(noexcept(adl_caller(...))这回落到
  3. adl_caller(..., priority_tag<0>) noexceptuser_method(dummy2)此时编译器还不知道。

不过,user_method(dummy2) 怎么样?上面叫3行?这是标准的意图吗?

对不起,如果我不够清楚。

#include <iostream>

template <unsigned N> struct priority_tag : priority_tag<N - 1> {};
template <> struct priority_tag<0> {};

template <typename T>
auto adl_caller(T t, priority_tag<1>) noexcept(noexcept(user_method(t)))
-> decltype(user_method(t)) {
std::cout << "first adl_caller overload" << std::endl;
user_method(t);
}

// tricky noexcept ...
template <typename T> void adl_caller(T, priority_tag<0>) noexcept {
std::cout << "second adl_caller overload" << std::endl;
}

template <typename T>
void magic(T t) noexcept(noexcept(adl_caller(t, priority_tag<1>{}))) {
adl_caller(t, priority_tag<1>{});
}

struct dummy {};
struct dummy2 {};

// un-commenting this line makes the above call to cout print '0'
// void user_method(dummy2);

void user_method(dummy)
{
// user_method(dummy2) is declared after this point
// this line prints '1', since magic falls back to the second adl_caller overload
std::cout << "noexcept?: " << noexcept(magic(dummy2{})) << std::endl;
std::cout << "dummy method called" << std::endl;
// however, the first adl_caller overload is called here ...
magic(dummy2{});
}

void user_method(dummy2)
{
std::cout << "dummy2 method called" << std::endl;
}

int main()
{
magic(dummy{});
}

最佳答案

[temp.point]/8 :

A specialization for a function template [...] may have multiple points of instantiations within a translation unit, and in addition to the points of instantiation described above, for any such specialization that has a point of instantiation within the translation unit, the end of the translation unit is also considered a point of instantiation. [...] If two different points of instantiation give a template specialization different meanings according to the one-definition rule, the program is ill-formed, no diagnostic required.

比较 [temp.dep.candidate] :

For a function call where the postfix-expression is a dependent name, the candidate functions are found using the usual lookup rules ([basic.lookup.unqual], [basic.lookup.argdep]) except that:

  • For the part of the lookup using unqualified name lookup, only function declarations from the template definition context are found.

  • For the part of the lookup using associated namespaces ([basic.lookup.argdep]), only function declarations found in either the template definition context or the template instantiation context are found.

If 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.

关于c++ - 与条件 noexcept 和重载不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43764311/

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