In this program, extract1
has a different output from all the rest. Why is that?
Specifically, why extract1
and extract2
have different outputs?
Can be reproduced in GCC, Clang, ICC, ZapCC, EllCC. But it cannot be reproduced in MSVC.
#include <iostream> | |
template <class T> | |
struct dispatch {}; | |
// --- extract 1 --- | |
namespace test1 | |
{ | |
template <class T> | |
void do_extract1(dispatch<T>) | |
{ | |
std::cerr << "T\n"; | |
} | |
template <class T> | |
void do_extract1(dispatch<T const&>) | |
{ | |
std::cerr << "T const&\n"; | |
do_extract1(dispatch<T>{}); | |
} | |
template <class T> | |
void do_extract1(dispatch<T const*>) | |
{ | |
std::cerr << "T const*\n"; | |
do_extract1(dispatch<T const&>{}); | |
} | |
inline void do_extract1(dispatch<char const&>) | |
{ | |
std::cerr << "char const&\n"; | |
do_extract1(dispatch<std::string const&>{}); | |
} | |
template <class T> | |
void extract1() | |
{ | |
do_extract1(dispatch<T>{}); | |
} | |
} | |
// --- extract 2 --- | |
template <class T> | |
void do_extract2(dispatch<T>) | |
{ | |
std::cerr << "T\n"; | |
} | |
template <class T> | |
void do_extract2(dispatch<T const&>) | |
{ | |
std::cerr << "T const&\n"; | |
do_extract2(dispatch<T>{}); | |
} | |
template <class T> | |
void do_extract2(dispatch<T const*>) | |
{ | |
std::cerr << "T const*\n"; | |
do_extract2(dispatch<T const&>{}); | |
} | |
inline void do_extract2(dispatch<char const&>) | |
{ | |
std::cerr << "char const&\n"; | |
do_extract2(dispatch<std::string const&>{}); | |
} | |
template <class T> | |
void extract2() | |
{ | |
do_extract2(dispatch<T>{}); | |
} | |
// --- extract 3 --- | |
namespace test3 | |
{ | |
template <class T> | |
void do_extract3(dispatch<T>) | |
{ | |
std::cerr << "T\n"; | |
} | |
template <class T> | |
void do_extract3(dispatch<T const&>) | |
{ | |
std::cerr << "T const&\n"; | |
do_extract3(dispatch<T>{}); | |
} | |
// Adjusted orders here | |
inline void do_extract3(dispatch<char const&>) | |
{ | |
std::cerr << "char const&\n"; | |
do_extract3(dispatch<std::string const&>{}); | |
} | |
template <class T> | |
void do_extract3(dispatch<T const*>) | |
{ | |
std::cerr << "T const*\n"; | |
do_extract3(dispatch<T const&>{}); | |
} | |
template <class T> | |
void extract3() | |
{ | |
do_extract3(dispatch<T>{}); | |
} | |
} | |
// --- extract 4 --- | |
struct test4 | |
{ | |
template <class T> | |
static void do_extract4(dispatch<T>) | |
{ | |
std::cerr << "T\n"; | |
} | |
template <class T> | |
static void do_extract4(dispatch<T const&>) | |
{ | |
std::cerr << "T const&\n"; | |
do_extract4(dispatch<T>{}); | |
} | |
static inline void do_extract4(dispatch<char const&>) | |
{ | |
std::cerr << "char const&\n"; | |
do_extract4(dispatch<std::string const&>{}); | |
} | |
template <class T> | |
static void do_extract4(dispatch<T const*>) | |
{ | |
std::cerr << "T const*\n"; | |
do_extract4(dispatch<T const&>{}); | |
} | |
template <class T> | |
static void extract4() | |
{ | |
do_extract4(dispatch<T>{}); | |
} | |
}; | |
int main() | |
{ | |
std::cerr << "---- extract 1 ----\n"; | |
test1::extract1<char const*>(); | |
std::cerr << "---- extract 2 ----\n"; | |
::extract2<char const*>(); | |
std::cerr << "---- extract 3 ----\n"; | |
test3::extract3<char const*>(); | |
std::cerr << "---- extract 4 ----\n"; | |
test4::extract4<char const*>(); | |
} | |
Case solved: ADL