【发布时间】:2017-10-01 12:53:14
【问题描述】:
我有一个与this 非常相似的问题。
简而言之,我有一个magic 方法,如果另一个方法是noexcept,它就是noexcept。
奇怪的是,这个“另一种方法”有两个重载,编译器选择第二个重载来判断magicnoexcept-ness。
但是,当稍后调用 magic 时,会调用 first 重载,但 magic 的 noexcept-ness 保持不变!
这是魔杖盒link
据我了解:
-
noexcept(magic(dummy2{}))来电 -
noexcept(noexcept(adl_caller(...))回退到 -
adl_caller(..., priority_tag<0>) noexceptsinceuser_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{});
}
【问题讨论】:
标签: c++ c++11 templates argument-dependent-lookup noexcept