c 17 как создать экземпляр шаблона с шаблоном, не относящимся к типу

#c #templates #c 17

Вопрос:

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

 template<typename Part>
class Body
{};

class Part1
{};

class Part2
{};

enum class E
{
    part1,
    part2,
};

template<E e>
class Factory
{
public:
    static unique_ptr<Body<>> create()
    {
        if (e == E::part1)
        {
            return make_unique<Body<Part1>>();
        }
        else
        {
            return make_unique<Body<Part2>>();
        }
    }   
};

int main()
{
    auto f=Factory<E::part1>();
    return 0;
}
 

Конечно,он выходит из строя во время компиляции, так как я мог получить свою порпузу?

Комментарии:

1. Body<Part1> и Body<Part2> являются несвязанными типами, поэтому у вас не может быть уникального указателя, который может указывать на любой из них. Может быть, использовать вариант ?

Ответ №1:

Здесь нет ничего с аргументом шаблона, не относящимся к типу, поэтому ваш заголовок сбивает с толку.

Я предполагаю, что ваша ошибка компилятора вызывает жалобы на

 Body<>
 

Что ж, это ошибка. Тело-это не тип, а шаблон. Для этого нужен аргумент, и по умолчанию его нет.

Код хочет, чтобы это было a Body<Part1> или a Body<Part2> , но нет такой вещи, как «Тело чего-либо», как вы подразумевали.

Вы можете иметь тип, который содержит любой тип, используя a variant . Например,

 using BodyPart = std::variant<Body<Part1>,Body<Part2>>;
 

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