Есть ли функция предупреждения без предупреждения для преобразования основных типов в строку - PullRequest
3 голосов
/ 16 ноября 2010

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

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 "

Насколько мне известно, причина предупреждения заключается в возможностях неявного преобразования при вызове <<. </p>

Эти неоднозначности в основном генерируются другими шаблонами, как показано ниже:

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

Но у них есть и другие преимущества, такие как работа с несколькими типами потоков. Поэтому я хотел бы сохранить их. Если я поверну второй шаблонв простой метод, например, для ostream неоднозначность очищается, но я ищу что-то, что позволяет сохранить оба шаблона. Есть ли универсальная функция, которая обеспечивает ту же простоту, не генерируя предупреждения с использованием описанных опций? Если нет, то чтолучший способ локально отключить выданное предупреждение?

Ответы [ 2 ]

2 голосов
/ 16 ноября 2010

Похоже, вы получите такое сообщение из сценария, подобного следующему:

#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.

1 голос
/ 16 ноября 2010

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

...