3

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

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++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second

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

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

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

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

4

2 回答 2

2

看起来你会从这样的场景中得到这样的消息:

#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引用。

于 2010-11-16T15:46:39.837 回答
1

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

于 2010-11-16T15:47:49.443 回答