是否有一个无警告的模板函数可以将基本类型转换为字符串

发布于 2024-10-02 17:33:56 字数 1005 浏览 11 评论 0原文

我想提供一个将大多数基本类型转换为字符串的模板化函数。 到目前为止我想出的最好的方法如下:

template<typename T> inline std::string anyToString(const T& var) {
  std::ostringstream o;
  o << var;
  return o.str();
}

该函数可以用于以下用途:

 class TimeError:public std::runtime_error{
     public:
       explicit TimeError(int time):std::runtime_error(anyToString(time)),
       mTime(time){};
     protected:
       int mTime;
     };

anyToString 和类似函数的问题是使用 gcc 版本 4.4.3 编译时生成歧义警告 -Wall -Wexta -Werror “ISO C++ 说这些是不明确的,即使第一个最差的转换比第二个最差的转换要好

据我所知,警告的原因在于调用时隐式转换的可能性<<。

这些歧义主要是由其他模板产生的,如下所示:

  template<typename T>
    T& operator<<(T& out, const SymRad& angle){
    return out << angle.deg();
  }

但这些模板还有其他优点,例如适用于多种流类型。 所以我想保留它们。如果我将第二个模板变成一个简单的方法,例如 ostream,那么歧义就会被消除,但我正在寻找某种东西。允许保留两个模板。 是否有一个通用函数可以提供相同的简单性,而不会使用所描述的选项生成警告? 如果没有,本地禁用发出的警告的最佳方法是什么?

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):std::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 ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你的往事 2024-10-09 17:33:56

看起来您会从这样的场景中收到这样的消息:

#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';
}

我建议改用 -pedantic 标志。 GCC 完全可以通过编译器扩展来编译它,而对于其他编译器来说,这将是一个直接错误。


至于你的补充:

  template<typename T>
    T& operator<<(T& out, const SymRad& angle){
    return out << angle.deg();
  }

但它们还有其他优点,例如适用于多种流类型。

这实际上不适用于多种流类型。例如,如果 Tstringstream,则 out << angle.deg(); 可能会返回对 ostream 的引用,该引用不能隐式向下转换回 stringstream 引用。

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.

沦落红尘 2024-10-09 17:33:56

据我所知,你的编译器支持 #pragma 用于此目的 - 我知道 VC++ 也支持。但是,您也可以只使用 boost::lexical_cast 。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文