0

Why can I typedef a template and construct it without declaring a constructor, but can't extend a template as a class and construct it without declaring a constructor?

In this example, the typedef works but the class does not. Surely somewhere C++ is generating a constructor for the typedef - why can't it do the same for the class?

#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;
}

Output

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&&’
ony_pox232
  • 171
  • 1
  • 10
  • Even if your `Event` wasn't templated, the result would be the same. – bipll Sep 03 '20 at 12:48
  • *"Surely somewhere C++ is generating a constructor for the typedef"* - You have a misunderstanding regarding `typedef`. It doesn't create new types. It simply provides a new name for an *existing* type. So nothing is "generated" for the typedef. The compiler sees `StringEvent`, and knows you mean `Event`, and so that's the type that `event` gets. Afterwards, the initialization of `event` proceeds as prescribed by the constructors available to `Event`. – StoryTeller - Unslander Monica Sep 03 '20 at 12:51
  • I don't understand what is happening... I have used this tactic of creating empty class definitions because C++ can differentiate between a class but not two typedefs that are actually the same type. And it was only when I tried this with a `string` version that it has failed. - Oh I understand why (not really though). You can extend a class that has a constructor with no params and not implement its constructor explicitly. – ony_pox232 Sep 03 '20 at 12:54
  • Indeed: the default constructor is generated if not user-provided. In C+11 you can [inherit constructors](https://en.cppreference.com/w/cpp/language/using_declaration#Inheriting_constructors) via `using`, but in C++98 you're out of luck. – Quentin Sep 03 '20 at 13:12

0 Answers0