I have an issue which is quite similar to this one.
In short, I have a magic
method, which is noexcept
if another method is noexcept
.
The weird thing is that this "another method" has two overloads, and the compiler chooses the second overload to determine magic
noexcept
-ness.
However, when magic
is called later on, the first overload is called, but the noexcept
-ness of magic
remains the same!
Here is the wandbox link
From what I understand:
noexcept(magic(dummy2{}))
callsnoexcept(noexcept(adl_caller(...))
which falls back toadl_caller(..., priority_tag<0>) noexcept
sinceuser_method(dummy2)
is not known by the compiler at this point.
Fair enough, however, how is user_method(dummy2)
called 3 lines above?
Is this intended by the Standard?
Sorry if I'm not clear enough.
#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{});
}
magic
method is linked to the first paragraph, but I have some trouble grasping the exact reason. Thanks a lot for the standard excerpts though – Darceydarci