C ++ Невозможно создать класс, расширяющий шаблон

Почему я могу ввести шаблон и построить его без объявления конструктора, но не могу расширить шаблон как класс и построить его без объявления конструктора?

В этом примере typedef работает, а класс - нет. Наверняка где-то C ++ генерирует конструктор для typedef - почему он не может сделать то же самое для класса?

#include <iostream>
#include <string>

template <class T>
class Event {
    public:
        Event(T data){this->data = data; std::cout<<data;}
        virtual ~Event(){}
        T data;
};

typedef Event<std::string> StringEvent;

class MyEvent : public Event<std::string> {};

int main()
{
    StringEvent event("hi"); // ok
    MyEvent event2("hi");    // no 
    
    return 0;
}

Вывод

main.cpp: In function ‘int main()’:
main.cpp:21:24: error: no matching function for call to ‘MyEvent::MyEvent(const char [3])’
     MyEvent event2("hi");
                        ^
main.cpp:14:7: note: candidate: MyEvent::MyEvent(const MyEvent&)
 class MyEvent : public Event<std::string> {};
       ^~~~~~~
main.cpp:14:7: note:   no known conversion for argument 1 from ‘const char [3]’ to ‘const MyEvent&’
main.cpp:14:7: note: candidate: MyEvent::MyEvent(MyEvent&&)
main.cpp:14:7: note:   no known conversion for argument 1 from ‘const char [3]’ to ‘MyEvent&&’

person ony_pox232    schedule 03.09.2020    source источник
comment
Даже если ваш Event не был создан по шаблону, результат был бы таким же.   -  person bipll    schedule 03.09.2020
comment
Наверняка где-то C ++ генерирует конструктор для typedef - у вас есть недопонимание относительно typedef. Он не создает новых типов. Он просто предоставляет новое имя для существующего типа. Таким образом, для typedef ничего не создается. Компилятор видит StringEvent и знает, что вы имеете в виду Event<std::string>, и это тот тип, который получает event. После этого инициализация event продолжается, как предписано конструкторами, доступными для Event<std::string>.   -  person StoryTeller - Unslander Monica    schedule 03.09.2020
comment
Я не понимаю, что происходит ... Я использовал эту тактику создания пустых определений классов, потому что C ++ может различать класс, но не два typedef, которые на самом деле являются одним и тем же типом. И только когда я попробовал это с string версией, это не удалось. - О, я понимаю, почему (хотя и не совсем). Вы можете расширить класс, у которого есть конструктор без параметров, и не реализовывать его конструктор явно.   -  person ony_pox232    schedule 03.09.2020
comment
Действительно: конструктор по умолчанию создается, если не предоставлен пользователем. В C + 11 вы можете наследовать конструкторы через using, но в C ++ 98 тебе не повезло.   -  person Quentin    schedule 03.09.2020