Is there a warning free template function to convert basic types to string
I want to provide a templated function that converts most basic types to string. The best I have come up with so far is the following:
template<typename T> inline std::string anyToString(const T& var) {
std::ostringstream o;
o << var;
return o.str();
}
The function can e.g. be used for the following:
class TimeError:public std::runtime_error{
public:
explicit TimeError(int time):st开发者_高级运维d::runtime_error(anyToString(time)),
mTime(time){};
protected:
int mTime;
};
The problem with anyToString and similar functions is the generation of ambiguity warnings when compiling with gcc version 4.4.3 -Wall -Wexta -Werror
"ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second
"
To my knowledge the reason for the warning lies in the implicit conversion possibilities when calling <<.
Those ambiguities are mainly generated by other templates as the following:
template<typename T>
T& operator<<(T& out, const SymRad& angle){
return out << angle.deg();
}
But those have other advantages like working for several stream types. So I would like to keep them. If I turn the second template into a plain method for e.g. ostream the ambiguity is cleaned, but I'm looking for sth. that allows keeping both templates. Is there a generic function that does provide the same simplicity without generating warnings using the described options ? If not, what is the best way to locally disable the issued warning ?
It seems you'd get such a message from a scenario like this:
#include <sstream>
#include <string>
#include <iostream>
struct Y {};
struct X
{
operator Y() const {return Y(); }
};
std::ostream& operator<< (std::ostream& os, X) { return os << "X"; }
std::ostream& operator<< (std::ostringstream& os, Y) { return os << "Y"; }
template<typename T> inline std::string anyToString(const T& var) {
std::ostringstream o;
o << var;
return o.str();
}
int main()
{
std::cout << anyToString(X()) << '\n';
}
I'd recommend using the -pedantic
flag instead. GCC compiles it at all thanks to a compiler extension, with other compilers this will be a straight error.
As to your addition:
template<typename T>
T& operator<<(T& out, const SymRad& angle){
return out << angle.deg();
}
But those have other advantages like working for several stream types.
This actually doesn't work for several stream types. E.g if T
is stringstream
, then out << angle.deg();
will likely return a reference to an ostream
which cannot be implicitly downcasted back to a stringstream
reference.
Your compiler supports a #pragma for this purpose, as far as I know - I know that VC++ does. However, you could just use a boost::lexical_cast, also.
精彩评论