3 ms·
Getting Java's generics out of your head when doing C++ is definitely a challenge. It's just so disappointing you cannot do something like: void myFunc(Lis
by Alupis 6y ago
Getting Java's generics out of your head when doing C++ is definitely a challenge. It's just so disappointing you cannot do something like:
void myFunc(List<? extends MyDataContainer<?>> list);
Instead you end up with a base class MyDataContiner and then manually extending it with something like MyDataContinerInt or MyDataContinerLong etc...
C++ templates may be very powerful, but limitations like this feel out of place in a language as bloated as C++ already is...
Admittedly, I still have much to learn about C++. It's been quite an experience, frustrating at times, learning this language.
- aw1621107 6y agoI think you can get something similar now with C++20 concepts? template<typename T, typename U> void my_func(std::vector<T>* vec) requires std::derived_from<T, my_data_container<U>>; (Probably mangled something, but the idea is there) Without concepts, you're left with SINFAE: template<typename T, typename U, typename = std::enable_if_t<std::is_base_of_v<my_data_container<U>, T>>> void my_func(std::vector<T>* vec); or just a regular function and a hope that anything wrong will be caught by the compiler: template<typename T, typename U> void my_func(std::vector<T>* vec) { // use my_data_container<U> somewhere and hope things blow up if something is wrong // Not 100% sure this is allowed, but something similar should be at least }
- dragontamer 6y agoI'm curious: what's wrong with myFunc(List<BaseClass * >) ?? EDIT: Remember, in C++, "BaseClass" cannot polymorph, only "BaseClass * " can. (BaseClass is where the data is stored precisely. If its 20 bytes of RAM, then DerivedClass might be 24 bytes of RAM, and therefore can't fit. But both BaseClass * and DerivedClass * are compatible with each other, and may convert into each other, as long as you know the pointer goes to the right kind of class) And if that's not sufficient, then a static_assert over the type information is probably what you need. Ex: template<class T> void myFunc(List<T> list){ static_assert(std::is_nothrow_convertible(T, BaseClass)); // I haven't tried, but this probably works } That's what I mean about C++ templates: they're a meta-language. You can add if-statements / else statements over type information at compile-time in C++. In this case, we've created a static_assert (aka: a compile-time error will pop up) if T does not convert into BaseClass (note: T may have a CopyConstructor(BaseClass), so maybe its not exactly tthe same concept as what you're trying to do... but this gives you an idea of C++isms...)
- Alupis 6y ago> I'm curious: what's wrong with myFunc(List<BaseClass * >) ?? Well, nothing I suppose, except BaseClass cannot then be a template, and you cannot have derived class-specific return types like a template would allow. So, having BaseClassInt type return int from some function but BaseClassLong return a long gets more challenging than it should be. (I recognize all my examples so far had a void return type, that was just for simplicity). > But both BaseClass * and DerivedClass * are compatible with each other, and may convert into each other, as long as you know the pointer goes to the right kind of class) Which loses type safety, unfortunately. > In this case, we've created a static_assert (aka: a compile-time error will pop up) if T does not convert into BaseClass I'll look into the static_assert() option, could prove useful in some cases. At the end of the day, there are two things at play here - my lack of C++ familiarity, and in some cases it's just how C++ is. It is a strange feeling though, having a language limit your expressiveness for the first time...
- dragontamer 6y ago> Well, nothing I suppose, except BaseClass cannot then be a template template <class T> void myFunc(List<T*>){ static_assert(stuff about T that you want to guarantee at compile time); } See here: https://en.cppreference.com/w/cpp/header/type_traits https://en.cppreference.com/w/cpp/header/type_traits For a list of common functions used for compile-time type checking.
- Alupis 6y agoThank you for this conversation. You've given me some homework to read up on, and I appreciate it a lot!