在C++11及更高版本中,是否允许在std
命名空间中为自定义类型特化std::to_string
?
namespace std {
string to_string(::MyClass const & c) { return c.toString(); }
}
使用示例:
int main() {
MyClass c;
std::cout << std::to_string(c) << std::endl;
}
在C++11及更高版本中,是否允许在std
命名空间中为自定义类型特化std::to_string
?
namespace std {
string to_string(::MyClass const & c) { return c.toString(); }
}
使用示例:
int main() {
MyClass c;
std::cout << std::to_string(c) << std::endl;
}
实际上,一切都很可能正常工作,但严格来说,标准并不保证会发生什么。
编辑:我没有访问官方标准的权限,因此以下内容来自免费工作草案(N4296):
17.6.4.2 命名空间使用如果我没记错的话,您可以简单地为通用类型重载to_string
:
template<typename T> to_string(const T& _x) {
return _x.toString();
}
这使得您的程序可以使用ADL(参数相关查找)来根据传递的类型正确选择相关的to_string
方法。
std
命名空间内还是外部? - James Adkisonto_string(myObject)
,但不适用于已经经过资格认证的函数调用,例如 std::to_string(myObject)
。 - jotikusing std::to_string; to_string(myObject);
这样做可以无论 myObject
的类型是什么都能得到正确的结果。 - spectrasclass A {};
std::string to_string(const A&)
{
return "A()";
}
int main()
{
A a;
using std::to_string;
std::cout << to_string(2) << ' ' << to_string(a);
}
std::to_string
,然后使用未限定调用的方式调用to_string()
。std::to_string
和::to_string
都可见,编译器会选择适当的重载函数。to_string
之前写using std::to_string
,或者担心忘记使用不带命名空间的to_string
,你可以创建一个辅助函数。template<typename T>
std::string my_to_string(T&& t)
{
using std::to_string;
return to_string(std::forward<T>(t));
}
to_string
的人,则此方法有效。如果有一个库调用std::to_string
并且您想为自己的类型更改它,则无法实现。std::to_string
时使库调用您的函数,我认为链接器替换可能会有所帮助。在TDD中使用时,当您依赖于无法编辑但仍必须在测试中模拟的库时。在这种情况下,您必须从替换后的库将所有调用转发到默认的std库,除了std::to_string
,它将调用您的实现,然后再调用您的to_string
或实际的std::to_string
。 - KulaGGinstd::to_string
,并在传递参数时尽可能使用.toString()
方法:#include <type_traits>
#include <iostream>
#include <string>
struct MyClass {
std::string toString() const { return "MyClass"; }
};
template<class T>
typename std::enable_if<std::is_same<decltype(std::declval<const T&>().toString()), std::string>::value, std::string>::type my_to_string(const T &t) {
return t.toString();
}
template<class T>
typename std::enable_if<std::is_same<decltype(std::to_string(std::declval<T&>())), std::string>::value, std::string>::type my_to_string(const T &t) {
return std::to_string(t);
}
int main() {
std::cout << my_to_string(MyClass()) << std::endl; // will invoke .toString
std::cout << my_to_string(1) << std::endl; //will invoke std::to_string
}
std::to_string
做个例外。或者作为替代方案,提供其他的特化方式,比如使用类似于template <class T> auto f(T && t) -> std::enable_if_t<ToStringSpec<std::decay_t<T> >::value, void> { ToStringSpec<std::decay_t<T> >()(std::forward<T>(t)); }
的方法。 - jotikoperator std::string
作为to_string
的替代方案怎么样? - jaques-samstd::to_string
或static_cast<std::string>
的情况。前者更美观。标准库如此不一致真是可惜。有些情况提供了自定义点,而有些情况则像std::to_string
一样。 - Sergey Kolesnik