C ++: эффективное добавление целых чисел в строки - PullRequest
3 голосов
/ 27 апреля 2010

Я знаю, как добавить целые числа в строки, но я не уверен, что делаю это эффективно. У меня есть класс, где мне часто приходится возвращать строку плюс целое число (каждый раз другое целое число), в Java я бы сделал что-то вроде

public class MyClass {
  final static String S = "MYSTRING";
  private int id = 0;

  public String getString() {
    return S + (id++);
  }
}

Но в C ++ я должен сделать;

class MyClass {
 private:
  std::string S; // For some reason I can't do const std::string S = "MYSTRING";
  int id;

 public:
  MyClass() {
    S = "MYSTRING";
    id = 0;
  }

  std::string getString() {
    std::ostringstream oss;
    oss << S << id++;
    return oss.str();
  }
}

Дополнительное ограничение: я не хочу (на самом деле, не могу) использовать Boost или любые другие библиотеки, мне придется работать со стандартной библиотекой.

Итак, дело в том; код работает, но в C ++ мне нужно создать кучу объектов ostringstream, поэтому кажется неэффективным. Чтобы быть справедливым, возможно, Java делает то же самое, и я просто не замечаю этого, я говорю, что это неэффективно, потому что я очень мало знаю о строках.

Есть ли более эффективный способ сделать это?

Ответы [ 4 ]

6 голосов
/ 27 апреля 2010

std::ostringstream - это «стандартный» способ сделать это в C ++. Возможно, вам удастся сделать что-то более эффективное с помощью некоторого пользовательского кодирования или кропотливого сравнения производительности ostringstream, itoa и sprintf на всех системах, где вы будете развертывать эту программу, но это, вероятно, не стоит усилие.

Я бы сказал, что настоящая проблема с решением std::ostringstream не в эффективности. Настоящая проблема в том, что код выглядит слишком сложным.

Я знаю, что вы не хотите использовать Boost, но если вы посмотрите на String Formatters of Manor Farm , вы можете просто скопировать (очень крошечное) определение шаблона lexical_cast<>() в вашу программу. Тогда ваш код будет выглядеть так:

std::string getString() {
    return S + lexical_cast<std::string>(id++);
}

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

3 голосов
/ 27 апреля 2010

Я уверен, что вы можете сделать следующее:

class MyClass 
{
 private:
  const std::string S; // For some reason I can't do const std::string S = "MYSTRING";
  int id;

 public:
  MyClass() :
     S( "MYSTRING" )
  {
    id = 0;
  }
}

Это совершенно не по моей голове и не проверено, хотя, поэтому я полностью ожидаю тонны отрицательных голосов: D хехехе

2 голосов
/ 27 апреля 2010

Чтобы добавить к другим ответам:

... код работает, но в C ++ мне нужно создать кучу объектов ostringstream, поэтому кажется неэффективным.Чтобы быть справедливым, возможно, Java делает то же самое, и я просто не замечаю этого ...

Java фактически делает то же самое;+ with Strings - это синтаксический сахар для StringBuffer.append(), поэтому они делают то же самое:

String f = "foo";
f += "bar" + "baz";

String f = "foo";
f = StringBuffer(f).append("bar").append("baz");
0 голосов
/ 27 апреля 2010

Вы правы, обычно ostringstream добавляет накладные расходы.

Это более эффективно, а ИМО более идиоматично ...

std::string adder() {
    static int i;
    char buf[32];
    snprintf(buf, sizeof(buf), "MYSTRING%i", i++);
    return buf;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...