Хорошо, я обычно в состоянии читать, понимать и исправлять ошибки компилятора. Но с этим я думаю, что мне нужна помощь.
Я хочу иметь 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;
}
Я понимаю, что это, вероятно, связано с неявными / явными конструкторами, семантикой копирования / перемещения и тому подобным.
Мой вопрос:
Как вы сказали, сообщение об ошибке говорит
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<>
, что накладывает ограничение на то, что ваш класс также должен быть тривиально конструируемым.
Справа от самого первого предложения описания библиотеки строк [strings.general]/1
:
В этом разделе описываются компоненты для управления последовательностями любого типа POD, не являющегося массивом. В этом разделе такие типы называются символоподобными типами, а объекты типоподобных типов называются символоподобными объектами или просто символами.
CustomClass
это не char-like
тип, потому что это не тип POD, и в результате он не может быть сохранен в basic_string
,
libc++
Реализация не компилируется, потому что она использует оптимизацию коротких строк, и при этом предполагает, что возможно держать массив CharT
в союзе без предоставления собственного конструктора.
Короче говоря, вы не можете использовать обычай class
потому что оптимизация короткой строки может использовать union
,
Тем не менее, вы можете использовать enum
тип.
Надо сделать довольно много работы, и вам нужно std::char_traits
для вашего типа.