Существует ли функция бесплатного шаблона предупреждения для преобразования основных типов в строку

StackOverflow https://stackoverflow.com/questions/4195764

  •  11-10-2019
  •  | 
  •  

Вопрос

Я хочу предоставить шаблонную функцию, которая преобразует большинство основных типов в строку. Лучшее, что я придумал до сих пор, - это следующее:

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

Проблема с любым toString и аналогичными функциями заключается в генерации предупреждений о неоднозначности при компиляции с 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();
  }

Но у них есть другие преимущества, такие как работа для нескольких типов потоков. Так что я хотел бы сохранить их. Если я превращаю второй шаблон в простой метод для EG Ostream, двусмысленность очищается, но я ищу STH. Это позволяет сохранить оба шаблона. Есть ли общая функция, которая обеспечивает ту же простоту без создания предупреждений, используя описанные параметры? Если нет, то как лучше всего локально Отключить выпущенное предупреждение?

Это было полезно?

Решение

Кажется, вы получите такое сообщение из такого сценария, как это:

#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();
  }

Но у них есть другие преимущества, такие как работа для нескольких типов потоков.

Это на самом деле не работает для нескольких типов потоков. Например, если T является stringstream, тогда out << angle.deg(); вероятно, вернет ссылку на ostream который не может быть неявно перевернуть обратно в stringstream ссылка.

Другие советы

Насколько я знаю, ваш компилятор поддерживает #Pragma для этой цели - я знаю, что VC ++ делает. Тем не менее, вы можете просто использовать Boost :: Lexical_Cast.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top