Как заставить `std :: basic_string & lt; CustomClass & gt;` скомпилировать?

Хорошо, я обычно в состоянии читать, понимать и исправлять ошибки компилятора. Но с этим я думаю, что мне нужна помощь.

Я хочу иметь std::basic_string<CustomClass> где CustomClass это класс. Я не хочу писать для него пользовательские классы char_traits и allocator, за исключением случаев, когда это абсолютно необходимо (т.е. я хочу использовать std::char_traits<CustomClass> а также std::allocator<CustomClass> если возможно).

Он прекрасно компилируется, если у меня нет конструкторов в CustomClass. Как только я добавляю один, появляются ошибки:

Вызов неявно удаленного конструктора по умолчанию 'std::__1::basic_string<CustomClass, std::__1::char_traits<CustomClass>, std::__1::allocator<CustomClass> >::__rep'

    #include <iostream>
#include <string>
//#include <vector>

class CustomClass;

typedef std::basic_string<CustomClass> InstanceString;
typedef std::basic_string<int> IntString;

class CustomClass
{
public:
CustomClass()
: m_X()
{
}

CustomClass(const int x)
: m_X(x)
{
}

private:
int     m_X;
};

int main(int argc, const char * argv[])
{
// This compiles fine
IntString s1({1, 2, 5});

// This would compile fine if there were no explicit constructors in Instance
//InstanceString s2e = InstanceString({Instance(), Instance(), Instance()});

// This generates errors
InstanceString s2 = InstanceString({CustomClass(1), CustomClass(3), CustomClass(5)});

std::cout << "Hello, World!\n";
return 0;
}

Я понимаю, что это, вероятно, связано с неявными / явными конструкторами, семантикой копирования / перемещения и тому подобным.

Мой вопрос:

  • как мне заставить его скомпилировать (т.е. какие конструкторы / что-то добавить в класс)
  • и как мне систематически выяснить, как исправить эти типы ошибок компиляции?

0

Решение

Как вы сказали, сообщение об ошибке говорит

Call to implicitly-deleted default constructor of 'std::__1::basic_string, std::__1::allocator >::__rep'

Я уверен, что __rep вот твой CustomClass, Он говорит, что пытается вызвать конструктор по умолчанию, но он был неявно удален (вы предоставили свой собственный конструктор). Я предполагаю, что basic_string использования std::is_default_constructible<>, Таким образом, вы должны предоставить конструктор по умолчанию, используя

CustomClass() = default;

как мыслящий утка предложил в комментариях.

Кажется вероятным, что он на самом деле использует std::is_trivially_default_constructible<>, что накладывает ограничение на то, что ваш класс также должен быть тривиально конструируемым.

2

Другие решения

Справа от самого первого предложения описания библиотеки строк [strings.general]/1:

В этом разделе описываются компоненты для управления последовательностями любого типа POD, не являющегося массивом. В этом разделе такие типы называются символоподобными типами, а объекты типоподобных типов называются символоподобными объектами или просто символами.

CustomClass это не char-like тип, потому что это не тип POD, и в результате он не может быть сохранен в basic_string,

libc++ Реализация не компилируется, потому что она использует оптимизацию коротких строк, и при этом предполагает, что возможно держать массив CharT в союзе без предоставления собственного конструктора.

4

Короче говоря, вы не можете использовать обычай classпотому что оптимизация короткой строки может использовать union,

Тем не менее, вы можете использовать enum тип.

Надо сделать довольно много работы, и вам нужно std::char_traits для вашего типа.

2
По вопросам рекламы [email protected]