Неоднозначная ошибка шаблона при добавлении std :: string в uint в Visual C ++ - PullRequest
0 голосов
/ 27 сентября 2010

Я получаю следующую ошибку при компиляции следующего кода в Visual Studio 2008 / Windows SDK 7

const UINT a_uint;
UINT result;

throw std::runtime_error( std::string("we did ") + a_uint +
                          " and got " + result );

Как ни странно, я закончил с таким результатом:

error C2782: 'std::basic_string<_Elem,_Traits,_Alloc> std::operator +(
                 const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem
             )' : template parameter '_Elem' is ambiguous

Может ли кто-нибудь объяснить, почему сообщение об ошибке не объясняет реальную проблему (что нет оператора для ввода строк в строки)?

Ответы [ 4 ]

6 голосов
/ 27 сентября 2010

Вы можете уменьшить это до

template<typename T>
void f(T, T);

int main() {
 f('0', 0); // is T int or char?
}

Вы пытаетесь добавить unsigned int в строку. Это не имеет смысла, и класс std::string не должен предпринимать каких-либо мер предосторожности для добавления неявных преобразований в char, потому что это скрыло бы такие потенциальные ошибки программирования.

Попробуйте преобразовать беззнаковое целое в std::string в десятичную / шестнадцатеричную / восьмеричную / и т. Д. Форму, а затем объединить (вы можете сделать это с помощью std::ostringstream или boost::lexical_cast) или исправить ошибку другим способом, который вам подходит ,

2 голосов
/ 27 сентября 2010

Используйте stringstream (определено в заголовке sstream), чтобы составить сообщение об ошибке:

std::stringstream ss;
ss << "we did " << a_uint << " and got " << result;
throw std::runtime_error(ss.str());
0 голосов
/ 27 сентября 2010

К std::string можно добавлять только другие std::string s, текст ASCIIZ по адресу, указанному const char*, и отдельные char -актеры.

Чтобы объединить другие типы, вы можете:

  • использовать поток:

    std :: ostringstream oss; oss << "мы сделали" << a_uint << "и получили" << результат; throw std :: runtime_error (oss.str ()); </p>

  • сначала преобразовать его в строковое представление:

    throw std :: runtime_error (std :: string ("мы сделали") + boost :: lexical_cast (a_uint) + "и получил" + повышение :: lexical_cast (результат));

Вы можете разумно задаться вопросом , почему C ++ не обеспечивает operator+(std::string&, X&) для X в {short, int, long, long long, float, double, unsigned short и т. Д.}, Или даже:

template <typename T>
std::string operator+(std::string& s, T& t)
{
    std::ostringstream oss;
    oss << t;
    return s + oss.str();
}

Во многих случаях это было бы удобно. Но потоки более мощные, так как вы можете настроить ширину и символ заполнения, точность с плавающей запятой и т. Д. Кроме того, char - это 8-битный целочисленный тип, так как компилятор может узнать, добавлять ли один символ с этим значением ASCII (например, 'A' для 65), или ASCII-представление числового значения ASCII "65"? (В настоящее время он не обрабатывает целые числа, поэтому его не следует путать с ASCII char). Или это должно работать для> = 16-битных чисел, но не для 8? Это сделало бы невозможным изменение размера переменных в / из 8-битных целых без необходимости выполнять сложный анализ влияния, чтобы увидеть, какие строковые операции необходимо переписать. Также рекомендуется минимизировать зависимости: некоторый небольшой, но, возможно, значительный процент единиц перевода, использующих строку, в настоящее время может не включать (и, следовательно, тратить время на разбор) (и, следовательно, ostream и т. Д.), И в целом циклические зависимости являются «запахом кода» и разочаровывающая тестируемость (строка зависит от ostringstream, зависит от строки ...).

0 голосов
/ 27 сентября 2010

В следующий раз, пожалуйста, опубликуйте полную ошибку (она должна продолжаться "с [_Elem =], может быть одной из [списка неоднозначных перегрузок]").

Проблема в том, что вы объединяете UINT со строкой std :: string.Это недопустимая операция, сначала нужно преобразовать UINT в std :: string (поищите в Google удобные функции).Компилятор пытается сделать все возможное и пытается сопоставить некоторые операторы std :: string с UINT.По-видимому, он находит некоторые совпадения, но это определенно не то, что вы ищете.

...