I'm trying to add a custom to_string
function for an enum class
that can be found using ADL, since overloading std::to_string
itself would be undefined behavior. I have the following code:
// -std=c++20
#include <string>
#include <iostream>
#include <cstdint>
namespace tns {
enum class MyEnum : std::int32_t {};
std::string to_string(MyEnum mine) {
return std::to_string(static_cast<std::int32_t>(mine));
}
void test() {
using namespace std;
MyEnum mine{2};
std::int32_t i = 1;
// (1)
// error: no matching function for call to 'to_string'
// note: candidate function not viable:
// no known conversion from 'std::int32_t' (aka 'int')
// to 'MyEnum' for 1st argument
// std::cout << to_string(i); // error
std::cout << " " << to_string(mine) << '\n';
}
}
void test2() {
using namespace std;
tns::MyEnum mine{2};
std::int32_t i = 1;
// (2)
std::cout << to_string(i); // OK
std::cout << " " << to_string(mine) << '\n';
}
int main() {
tns::test();
test2();
return 0;
}
Why does the code at (1) in tns::test
trigger a compiler error, but not the same code at (2) in ::test2
? I have looked through the ADL rules but can't figure it out.
With tns::to_string
you hide the to_string
in std
that would otherwise be considered since you did using namespace std;
. using namespace ...
does not add all things in the used namespace into the current one.
In order to make std::to_string
come out of hiding, bring that overload into the tns
namespace with
using std::to_string;
They now both participate in overload resolution when using to_string
.
Both to_string
s are found in their respective namespace via ADL. None hides the other and they compete on equal terms so to speak.