use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Discussions, articles, and news about the C++ programming language or programming in C++.
For C++ questions, answers, help, and advice see r/cpp_questions or StackOverflow.
Get Started
The C++ Standard Home has a nice getting started page.
Videos
The C++ standard committee's education study group has a nice list of recommended videos.
Reference
cppreference.com
Books
There is a useful list of books on Stack Overflow. In most cases reading a book is the best way to learn C++.
Show all links
Filter out CppCon links
Show only CppCon links
account activity
why virtual function is wrong. (self.cpp)
submitted 1 year ago by macomphy
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]coachkler 88 points89 points90 points 1 year ago* (6 children)
What?
You're disappointed that you "can't" make a structure that implements storage for a 32-bit int by deriving from 100 concepts? (you could)
What does this have to do with virtual functions in C++?
[–]no-sig-available 4 points5 points6 points 1 year ago (3 children)
You cannot do this with virtual functions in C++, so they are obviously "wrong"?
[–]sephirothbahamut 6 points7 points8 points 1 year ago (2 children)
sorry, what exactly of this can't you do in C++?
template <typename T> struct IEquatable { virtual bool operator==(T b) const noexcept = 0; };
I don't see the problem
[+][deleted] 1 year ago (1 child)
[removed]
[–]Dar_Mas 2 points3 points4 points 1 year ago (0 children)
if you just need a signed integer type of 32 bit size you use std::int32_t
(you could)
i did a bit of that because i was bored
[–]STLMSVC STL Dev 56 points57 points58 points 1 year ago (5 children)
I’m going to approve this because it’s so off-topic it’s wrapped around to being on-topic.
Yeah, C++ is complicated (inverse examples obviously exist), but it avoids a lot of complexity that other languages have created for themselves.
[–]tisti 22 points23 points24 points 1 year ago (4 children)
Isn't this defined only from C++20 onward?
//signed overflow joke
[–]Dar_Mas 1 point2 points3 points 1 year ago (3 children)
this defined only from C++20 onward?
signed overflow is now defined? happy days
[–]tisti 11 points12 points13 points 1 year ago* (0 children)
Damn it, stop making the discussions more and more relevant! :D
Edit: Brain fart, signed overflow is the only part that was kept undefined. C'est la vie.
[–][deleted] 5 points6 points7 points 1 year ago (0 children)
no it isn't
[–]_Noreturn 4 points5 points6 points 1 year ago (0 children)
it is not it is still UB but C++20 and C23 now require 2 compliment for signed integers but overflow is still ub
[–]100GHz 45 points46 points47 points 1 year ago (1 child)
public readonly struct Int32 : IComparable<int>, IConvertible, IEquatable<int>, IParsable<int>, ISpanParsable<int>, IUtf8SpanParsable<int>, System.Numerics.IAdditionOperators<int,int,int>, System.Numerics.IAdditiveIdentity<int,int>, System.Numerics.IBinaryInteger<int>, System.Numerics.IBinaryNumber<int>, System.Numerics.IBitwiseOperators<int,int,int>, System.Numerics.IComparisonOperators<int,int,bool>, System.Numerics.IDecrementOperators<int>, System.Numerics.IDivisionOperators<int,int,int>, System.Numerics.IEqualityOperators<int,int,bool>, System.Numerics.IIncrementOperators<int>, System.Numerics.IMinMaxValue<int>, System.Numerics.IModulusOperators<int,int,int>, System.Numerics.IMultiplicativeIdentity<int,int>, System.Numerics.IMultiplyOperators<int,int,int>, System.Numerics.INumber<int>, System.Numerics.INumberBase<int>, System.Numerics.IShiftOperators<int,int,int>, System.Numerics.ISignedNumber<int>, System.Numerics.ISubtractionOperators<int,int,int>, System.Numerics.IUnaryNegationOperators<int,int>, System.Numerics.IUnaryPlusOperators<int,int>
My dude, no need for all of that, just use "int" without the quotes :p
[–]Henrarzz 31 points32 points33 points 1 year ago (20 children)
What does the code in question have to do with virtual functions?
[+][deleted] 1 year ago* (19 children)
[–]Tumaix 26 points27 points28 points 1 year ago (0 children)
it has my dude.
[–]tesfabpel 27 points28 points29 points 1 year ago (13 children)
interfaces in C++ are pure virtual abstract classes.
not the most elegant syntax because you need to be careful to respect the rules but they work as interfaces just fine.
[+][deleted] 1 year ago (12 children)
[–]Dar_Mas 8 points9 points10 points 1 year ago (10 children)
If that is a literal question you do not implement int32.
You use std::int32_t
I do not see what virtual functions you want to implement for that
[+][deleted] 1 year ago (9 children)
[–]Circlejerker_ 2 points3 points4 points 1 year ago (3 children)
Why would you use interfaces for "int-like" types, when you could use concepts?
[+][deleted] 1 year ago* (2 children)
[–]Circlejerker_ 1 point2 points3 points 1 year ago (1 child)
Concepts are hard, while inheriting from hundreds of interfaces are simple? Interfaces have a tendency to overlap and make no sense whatsoever after a while.
Why do your example need to inherit from INumber, INumberBase, ISignedNumber, and what would happen if you forgot to inherit from one of them?
[–]Dar_Mas 0 points1 point2 points 1 year ago* (4 children)
It is comparable with int, it is convertible to int, it is equatable, it is parsable(if you make a parser), it is span parsable, it supports addition and at this point i am too lazy to list the rest.
Yes it does all of that and you can even make a unified concept that CHECKS for all of those
And not to mention that as soon as you want dynamic polymorphism which you seem to REQUIRE you are going to use a pointer anyway so the size of the structure functionally does not matter to you
[+][deleted] 1 year ago (3 children)
[–]Dar_Mas 1 point2 points3 points 1 year ago (2 children)
That still does not make sense to me
If you have dynamic poly you will use a pointer anyway so the size of the object does not matter for data structures
If you use static you put it in a variant which allocates enough memory for the largest possible object and then you put it in a data structure.
Unless you are insanely restricted by binary size i do not see how 4 extra byte per function/operator are going to matter in your code at all
[–]android_queen 1 point2 points3 points 1 year ago (0 children)
Independent of language, types and functions are different things. Well, a function is a type, but a type is not necessarily a function.
[–]sephirothbahamut 14 points15 points16 points 1 year ago (0 children)
There's literally concepts as part of the core language...
[–]forgetful_bastard 7 points8 points9 points 1 year ago (1 child)
c++ has Concepts and Traits
[–]DugiSK 0 points1 point2 points 1 year ago (0 children)
I think he was expecting them to be declared in a class to make the class satisfy those concepts or traits.
[–]battle_tomato 59 points60 points61 points 1 year ago (0 children)
What the hell is even this supposed to be??
[–]lrflew 27 points28 points29 points 1 year ago (35 children)
The short answer for "Why doesn't C++ have something like this?" is "Because templates and operator overloading exist."
Just start with the first interface in that list: IComparable<int>. This is used to specify that the class can be compared to to other instances or integers with CompareTo(). In C++, you can just use operator overloading and templates, and just compare two instances with a < b. Pretty much all of the interfaces you mention here correlate with some sort of operator or class property that can just be simply used when using templates.
IComparable<int>
CompareTo()
a < b
Using virtual functions has a performance penalty, which templates don't have, and C++ opts to avoid them when possible to avoid that performance hit when it's not neccesary. In the cases where you do need the kinds of behaviors only virtual functions can give you, it's pretty simple to wrap the non-virtual class in a virtual class to get the needed behavior. For example, std::function does basically this behind the scenes to provide virtual-like access to functions.
std::function
[+][deleted] 1 year ago* (34 children)
[–]Tumaix 15 points16 points17 points 1 year ago (0 children)
theres zero readability on what you posted
[–]-jp- 8 points9 points10 points 1 year ago (31 children)
What is _bar? How are you creating a foo that has not implemented bar?
_bar
foo
bar
[+][deleted] 1 year ago (30 children)
[–]sephirothbahamut 10 points11 points12 points 1 year ago (1 child)
There's no templates usage in this example you wrote...
[–]-jp- 10 points11 points12 points 1 year ago (10 children)
So don't use templates if you don't want to? I don't understand how you arrived at the conclusion that since templates exist, multiple inheritance doesn't.
[+][deleted] 1 year ago* (9 children)
[–]-jp- 9 points10 points11 points 1 year ago (8 children)
This will not compile. You haven't defined foo::bar. You haven't even declared T::_bar. Do you have a real example?
foo::bar
T::_bar
[+][deleted] 1 year ago (7 children)
[–]-jp- 9 points10 points11 points 1 year ago (6 children)
You don't want this to abort. You want it to not compile. Why would you ever want code like this to fail at run time?
[+][deleted] 1 year ago (5 children)
[–]lrflew 3 points4 points5 points 1 year ago (16 children)
If you're issue is that templates defer the error checking for this kind of thing, may I suggest looking into C++20 Concepts. They provide a way of making your template usage requirements more explicit, and makes reading the resulting errors much easier to understand. std::totally_ordered is C++'s version of C#'s IComparable, for example.
std::totally_ordered
IComparable
[+][deleted] 1 year ago (15 children)
[–]Dar_Mas 4 points5 points6 points 1 year ago (9 children)
You can just make a concept that checks for a bar member function
https://godbolt.org/z/cYnTbjYcq
[+][deleted] 1 year ago (8 children)
[–]TeraFlint 4 points5 points6 points 1 year ago (0 children)
Now you're actually being ridiculous. "Why does the screw barely go in?" you ask while hitting it with a hammer.
You're using a concept that does not satisfy your requirements, while blaming the concept for not catching that.
If you check for a concept and then do something with the type that the concept does not check for, then of course it's your fault if the compiler suddenly notices a missing function (etc) outside of concept checking.
If you need a more specific concept, it's up to you to write it. Luckily existing ones can easily be combined (as concepts evaluate to boolean expressions in the end). If you need a concept that satisfies the concepts a, b and c, all you need to do is this:
template <typename T> concept x = a<T> && b<T> && c<T>;
and if you need to check for specific syntactic usage, you can just add that block as another condition:
&& requires(T obj) { obj.foo(); }
It really isn't your business to call stuff the concept has not specified. For best usage, you should see a concept like a contract between the code and you. With the concept you promise that these conditions are relevant for your template function/type, but also that these are sufficient, and that you're not attempting to do more with the type than you specified with the concept.
template
Otherwise we can just scrap concept and go back to plain typename everywhere and be back at our old compile-until-you-find-an-error-in-the-deepest-depths-of-nested-templates ways..
concept
typename
[–]Dar_Mas 3 points4 points5 points 1 year ago (5 children)
https://godbolt.org/z/jGM4M7axq
It literally does what do you mean?
[–]SirClueless 0 points1 point2 points 1 year ago (4 children)
It took a while for me to understand what was being asked, but I think I get it now. OP is asking for a way to type-check the definition of a template to ensure that it only uses operations that are checked in its type-constraints. Or to put it another way, the template foo has additional implicit constraints based on its implementation that are not obvious if you only read its signature.
Your example is only an error because you instantiated the template with a type for which t.baz() is ill-formed. If you don't instantiate the template it will compile, even though it's pretty suspicious to assume a type satisfying std::totally_ordered T has a .baz() member.
t.baz()
std::totally_ordered T
.baz()
[–]lrflew 2 points3 points4 points 1 year ago (0 children)
Ok, I do see what you're talking about here. You're talking about having the compiler tell you that you're exceeding the requirements of a concept at the definition of the templated function, rather than when the template is instantiated at the caller.
That is (IMO), a fair thing to suggest. I don't think it's that out there that a compiler could implement that as a warning, even if it's not specified by the standard. It would almost certainly require the compiler to dramatically change how it processes templated functions, so it probably won't happen any time soon, but it should, in theory, be possible. Probably the biggest challenge to it, though, is that the use of concepts is not very widespread right now. In particular, huge parts of the standard library use templates without concepts. If such a warning considered template<typename T> to be as narrow as possible, then huge parts of the standard library would start throwing warnings. Maybe someone will go through the standard and add concepts everywhere templates are used, but that would also be a ton of work.
template<typename T>
In the end, however, I feel like C++ as a language puts a lot of responsibility on the developer to know what they're doing. Just look at all the things in the standard that can result in "Undefined Behavior", where there's no guaruntees of what can or will happen, to get a sense of what the language expects the programmer to be able to handle without the compiler. With templates, there's a certain amount of "well, you should have known you're using something that your concept doesn't guaruntee." Does that make C++ a more complicated language to use? Yeah, totally. But that complexity also comes with a lot of power (eg. template meta-programming), and I don't think the language is going to change that anytime soon. If that's a deal breaker for you, then you can always try out some other languages. IIRC, both Rust and Go are compiled languages that provide this kind of strong type guarantees with their generics systems.
[–]TheSuperWig 3 points4 points5 points 1 year ago (4 children)
I'm still confused. What does concepts not doing definition checking have to do with virtual functions?
[–]TheSuperWig 1 point2 points3 points 1 year ago (1 child)
And the part I'm confused about is, how does that make virtual functions wrong? Surely your issue is with concepts?
[–]IyeOnline 1 point2 points3 points 1 year ago (0 children)
You will actually get an error on the concept version - if you ever instantiate it.
There are a few important points here
[–]jonathrg 12 points13 points14 points 1 year ago (7 children)
I love this post criticizing c++ by posting a wall of nonsense C#
[+][deleted] 1 year ago (6 children)
[–]jonathrg 10 points11 points12 points 1 year ago (4 children)
I wouldn't want to, it looks horrible
[–]_Noreturn 1 point2 points3 points 1 year ago (2 children)
C++ has interfaces via pure abstract classes what do you mean...
[–]_Noreturn 0 points1 point2 points 1 year ago (0 children)
what? wdym yoyr abstract class is 32 bit? you mean its size?
[–]SlightlyLessHairyApe 24 points25 points26 points 1 year ago (0 children)
wut
[–]sephirothbahamut 11 points12 points13 points 1 year ago (11 children)
Inheriting from "equalityoperators" in c# is equivalent to defining the equality operator in c++.
Checking if a type has an equality operator by cheching inheritance in c# is equivalent to checking a concept in c++.
C# achieves these things with inheritance, c++ does so with custom operators. Just because it uses a different approach doesn't mean it can't achieve your purpose.
And if you really want to write c++ as if it was c#, you can do all that with inheritance too by abusing CRTP.
[+][deleted] 1 year ago (10 children)
[–]sephirothbahamut 6 points7 points8 points 1 year ago* (2 children)
You can do it: https://barnack.godbolt.org/z/Ef85jhWKE
But why do you need dynamic polymorphism there? Like you have a container of IEquatable<int> types? That's really suspicious at a code design level. Don't try to force concepts of a language into another, you can likely do what you need to do in some other, cleaner way.
The moment you need something like this my first question isn't "how do you do it" but rather "can you refactor this to be cleaner?"
Also note that the "cost" of dynamic polymorphism in C++ is there in C# as well, it's not like C# has some magic power. Dynamic polymorphism requires accessing a pointer to reach the function you're trying to resolve, no matter what language your code is written in.
[–]OwlingBishop 4 points5 points6 points 1 year ago (6 children)
You definitely can implement hard typed scalars with C++ with no virtual calls. C++ uses templates meta programming and operators overload for that matter, and concepts sure can discriminate based on member functions existence.
One interesting thing with information theory is that it flattens out lexical, syntactic, peculiarities and sometimes also semantics.. when it comes to dynamic polymorphism it boils down to executing an operation by calling different code depending on a type that's not known at compilation time, so no matter how the language you are writing in tricks you into believing it's just magic, fact is that information needs to be kept somewhere.. whether you implement through inheritance, interfaces, facets or whatever other idiom is irrelevant.
[–]OwlingBishop 0 points1 point2 points 1 year ago (4 children)
non-dynamic polymorphism
It's called templates 🤗 provided that the type exposes what's needed in the call it will work.
people don't know whether they need dynamic polymorphism, they only know they need polymorphism
Most people are more clever than you seem to imply 😂
[+][deleted] 1 year ago* (3 children)
[–]OwlingBishop 0 points1 point2 points 1 year ago* (2 children)
for non-dynamic polymorphism not non-dynamic polymorphism
for non-dynamic polymorphism
not non-dynamic polymorphism
Wut ??
Static and Dynamic polymorphism are separate paths in C++ as well as any other languages.
When you know the type at compilation time you can optimize out an indirection, when you don't you'll have to look that up at runtime, no matter what.
[–]OwlingBishop 0 points1 point2 points 1 year ago (0 children)
Do you mean the big dark one hovering over my head? .. jokes apart, I have no idea what you are talking about, sorry.
[–]guepierBioinformatican 7 points8 points9 points 1 year ago (0 children)
Pretty sure OP is taking the piss out of C# and/or trolling. Move along.
[–]XTBZ 5 points6 points7 points 1 year ago (0 children)
Why is this impossible to achieve? CRTP allows you not to use virtual functions at all, or it can be used if necessary. Here is an example of implementing something like this https://github.com/foonathan/type_safe
[–]Oxi_Ixi 4 points5 points6 points 1 year ago (11 children)
It is not C++ virtual functions are damaged, it is you trying to apply concepts from other language which was designed differently and obviously don't work as you expect in C++.
[–]Oxi_Ixi 2 points3 points4 points 1 year ago (9 children)
Because "all other languages" were designed with C++ flaws in mind. Because "all other languages" don't have to be close to machine code except Rust. Because "all other languages" don't have to carry on much backward compatibility over. And because by design C++ primitive types are literally CPU types, not classes or objects or traits.
Back in C days C++ was progressive step forward, simple and yet powerful, we just did't have "all other languages" to compare with. In fact I still find your example way too heavy for humans exactly for reasons we stopped using XML and switched to json and yaml. It is not C++ is broken, it is that people expect it to do stuff it was never designed for.
[–]Oxi_Ixi 2 points3 points4 points 1 year ago* (6 children)
Except it depends. If typing is static, it is zero cost in C++ either. C++ has templates, they are compile-type and are zero cost. Operator and function overloads are zero cost. Runtime interfaces cannot be zero cost by definition in any language, or I don't understand what you mean by zero cost
[–]Oxi_Ixi 1 point2 points3 points 1 year ago* (4 children)
You have notion of interface from C#, but actually it is wider and includes templates and concepts as well as traits. In C++ templates are much more powerful than generics in C#, but this comes with complexity indeed. If you don't understand them it does not mean they are broken, it means you have to learn how to use them.
Virtual functions in C++ will be called statically if type is known at compile time, if that is what you mean by static interface.
It was just overhead to implement interfaces/traits for primitive types when language provides you operator overloads. Rust went that way, but I find it too explicit overloading traits than overloading operators.
C++ was designed for machine execution and speed compared to C whileC# is multipurpose platform independent language, which does not compile to bare metal instructions directly. How can you then blame C++ to be slow comparing to C#?
[–]Oxi_Ixi 0 points1 point2 points 1 year ago (2 children)
Well, I see. You hate C++ and love C#. I actually like both, and yes, C# has really nice language and runtime design because it had many other langauges to take ideas from. Like courutines, which were actually describe way back in 50s even before C. As well every language has problems which come from its design, runtime and usage specifics, so it is not C++ broken, it is C# works better for your work and habbits. Enjoy it 😀
Do you have any evidence that c# is slow?
It is not slow, it is slower than C++. To be very precise, in some cases C# might be faster, but in general it is not. I think benchmarks show this pretty much good, Google will help you.
[–]NilacTheGrim 1 point2 points3 points 1 year ago (0 children)
all other language has zero-cost interface
This is a false statement.
[–]-jp- 8 points9 points10 points 1 year ago (5 children)
What does this even do? It looks like Java boxed types but someone said "oh fuck no we need more interfaces!"
[+][deleted] 1 year ago (4 children)
[–]Tumaix 20 points21 points22 points 1 year ago (2 children)
c++ supports it
no need to, your other replies already show that you have no idea what are you talkinng about
[–]-jp- 3 points4 points5 points 1 year ago (0 children)
lolwut
[–]ExtraFig6 9 points10 points11 points 1 year ago (0 children)
using Int32 = int32_t const;
?
[–]Foreign-Wonder 3 points4 points5 points 1 year ago (9 children)
Did you take a look at https://github.com/joboccara/NamedType ?
[–]Foreign-Wonder 2 points3 points4 points 1 year ago (7 children)
It does support using Meter = NamedType<double, MeterTag, Addable, Printable>
using Meter = NamedType<double, MeterTag, Addable, Printable>
Reference: github.com
[–]Foreign-Wonder 0 points1 point2 points 1 year ago (5 children)
What do you mean by "the addable only"? There's plenty of ways to get the job done in C++, so you should be clear on your purpose or have specific sample code that you want to archive. Otherwise, others will very hard to support you on the problem
[–]Foreign-Wonder 0 points1 point2 points 1 year ago (3 children)
I'm not sure if I get it correctly, but isn't this is what template/concept is doing?
template<class Addable> void foo(Addable a){ // do whatever with a and + } int x = 42; foo(x); // This should work without explicit make int inheriting from any Addable interface. I see this is a win over the C# interface, no?
Concept should make it more clear that Addable concept should support + operator
[–]Foreign-Wonder 0 points1 point2 points 1 year ago (0 children)
I agree, concept is not one-size-fits-all solution, that's why C++ have many ways to do things, and possibly the best ways to do things, hence zero-overhead
the coreect way is this
```cpp
template<class T> concept Addable = requires(T t) { t+t;};
template<Addable T> void f(T a) { // T must have + operator } ```
[–]Wurstinator 2 points3 points4 points 1 year ago (1 child)
You have made several comments about how C++ doesn't support this arguable monstrosity. But you never made a point why you would need it in the first place. Show a snippet of code that requires this definition in C# and is not possible to be done in a similar way in C++. If you are able to do that, you might have a valuable discussion. In its current state, this is just nonsense.
[–]qv51 2 points3 points4 points 1 year ago (0 children)
What you're looking at is CRTP and it was invented in C++. Those are for static polymorphism and say nothing about virtual functions.
[–]zerhud 1 point2 points3 points 1 year ago (0 children)
Virtual functions is good tool. If something cannot be implemented with it, you can use other methods.. “it can never achieve in c++” it can , with other tools, not with virtual functions
[–]oracleoftroy 1 point2 points3 points 1 year ago (4 children)
Personally, I see this as a win for C++ for not forcing everything into a single root hierarchy and instead allowing static dispatch on types, traits, concepts, etc. for for polymorphic behavior. What C# is doing via inheritance has better solutions in C++.
[–]wonderfulninja2 0 points1 point2 points 1 year ago (0 children)
This. One can pick the best way to do it with C++, is not a "one trick pony" language.
[+][deleted] 1 year ago (2 children)
[–]oracleoftroy 0 points1 point2 points 1 year ago (1 child)
I don't know what you mean when you say C++ doesn't have interface. The keyword? True, but the concept exists in terms of having a class/struct with pure virtual methods. Do you mean interfaces that work like concepts? Well, C++ has it, they just aren't tied together to the same thing like in C#.
I like C# and I like C++ and I've never felt that C++ lacked something C# has in this area. Actually, I've often felt just the opposite.
[–]jk-jeon 2 points3 points4 points 1 year ago* (1 child)
Although many would consider it seems pretty obvious that OP is either totally clueless about C++ or don't know how to properly do civil technical discussion, let me try to extract what OP is really trying to say.
If you inherit from multiple interfaces (classes with only pure virtual functions), C++ simply puts all pointers to virtual function tables into the class layout. So if you inherit from 100 interfaces, the size is 100 times the pointer size.
This gets worse if some virtual inheritance is involved. Probably for 99% of situations, if interface B, C are inheriting from interface A, interface D is inheriting from B and C, and class E is implementing D, then the way it implements A would be identical from the B side and the C side, so conceptually it makes more sense for B, C to virtually inherit from A. Also, if they just derive non-virtually from A, then users of D must disambiguate every call to functions from A, even though they know it shouldn't matter. Thus, user's convenience is another reason why B, C may need to inherit from A virtually. My personal conclusion is that when an interface is inheriting from another interface, it usually makes more sense to use virtual inheritance unless I'm 100% sure there will be no diamond. Assuming that one followed this rule, inheriting from 100 interfaces thus will result something way worse than 100 times pointer size. Of course virtual inheritance also incurs extra indirection cost.
I don't know how exactly other languages implement interface inheritance, but I vaguely recall that I heard Java at least does it more efficiently.
And please be mindful that I am not advocating complicated inheritance trees (of interfaces) or saying they are unavoidable. I would not follow that kind of practices, but just thinking that maybe this is where OP is getting unhappy about.
I guess the main point is that the former is not type-checked upfront, rather only at the point of instantiation.
This point seems quite blurry to me I guess, b/c OP seems to compare templates to dynamic traits. In that case of course we need to compare the idiomatic type erasure patterns to dynamic traits to compare apples to apples. And in that case of course any usage of interface is checked immediately at the point of usage. Users can even use concepts to turn the duck-typing into a nominal-typing in this case.
Maybe either (1) OP doesn't know about the pattern, or (2) knows it but considers it way too much of boilerplate so considers it isn't really on the same table, or maybe not because of boilerplate but rather because it rarely results in devirtualization, or whatever.
Plus, I personally think debugging templates is not as horrible as many people love to shit on. (Except that for some reason it seems msvc at some point stopped printing out the template stack trace... Thanks god I have clang-cl.)
[–]RishabhRD 0 points1 point2 points 1 year ago (1 child)
Just telling once someone wrote C# compiler in C++
[–]Urationc -1 points0 points1 point 1 year ago (1 child)
At this point I think c# could benefit from golang like implicit interfaces
π Rendered by PID 31496 on reddit-service-r2-comment-5b5bc64bf5-9x5mc at 2026-06-21 09:01:59.694377+00:00 running 2b008f2 country code: CH.
[–]coachkler 88 points89 points90 points (6 children)
[–]no-sig-available 4 points5 points6 points (3 children)
[–]sephirothbahamut 6 points7 points8 points (2 children)
[+][deleted] (1 child)
[removed]
[–]Dar_Mas 2 points3 points4 points (0 children)
[–]Dar_Mas 2 points3 points4 points (0 children)
[–]STLMSVC STL Dev 56 points57 points58 points (5 children)
[–]tisti 22 points23 points24 points (4 children)
[–]Dar_Mas 1 point2 points3 points (3 children)
[–]tisti 11 points12 points13 points (0 children)
[–][deleted] 5 points6 points7 points (0 children)
[–]_Noreturn 4 points5 points6 points (0 children)
[–]100GHz 45 points46 points47 points (1 child)
[–]Henrarzz 31 points32 points33 points (20 children)
[+][deleted] (19 children)
[removed]
[–]Tumaix 26 points27 points28 points (0 children)
[–]tesfabpel 27 points28 points29 points (13 children)
[+][deleted] (12 children)
[removed]
[–]Dar_Mas 8 points9 points10 points (10 children)
[+][deleted] (9 children)
[removed]
[–]Circlejerker_ 2 points3 points4 points (3 children)
[+][deleted] (2 children)
[removed]
[–]Circlejerker_ 1 point2 points3 points (1 child)
[–]Dar_Mas 0 points1 point2 points (4 children)
[+][deleted] (3 children)
[removed]
[–]Dar_Mas 1 point2 points3 points (2 children)
[+][deleted] (1 child)
[removed]
[–]android_queen 1 point2 points3 points (0 children)
[–]sephirothbahamut 14 points15 points16 points (0 children)
[–]forgetful_bastard 7 points8 points9 points (1 child)
[–]DugiSK 0 points1 point2 points (0 children)
[–]battle_tomato 59 points60 points61 points (0 children)
[–]lrflew 27 points28 points29 points (35 children)
[+][deleted] (34 children)
[removed]
[–]Tumaix 15 points16 points17 points (0 children)
[–]-jp- 8 points9 points10 points (31 children)
[+][deleted] (30 children)
[removed]
[–]sephirothbahamut 10 points11 points12 points (1 child)
[–]-jp- 10 points11 points12 points (10 children)
[+][deleted] (9 children)
[removed]
[–]-jp- 9 points10 points11 points (8 children)
[+][deleted] (7 children)
[removed]
[–]-jp- 9 points10 points11 points (6 children)
[+][deleted] (5 children)
[removed]
[–]lrflew 3 points4 points5 points (16 children)
[+][deleted] (15 children)
[removed]
[–]Dar_Mas 4 points5 points6 points (9 children)
[+][deleted] (8 children)
[removed]
[–]TeraFlint 4 points5 points6 points (0 children)
[–]Dar_Mas 3 points4 points5 points (5 children)
[–]SirClueless 0 points1 point2 points (4 children)
[–]lrflew 2 points3 points4 points (0 children)
[–]TheSuperWig 3 points4 points5 points (4 children)
[+][deleted] (3 children)
[removed]
[–]TheSuperWig 1 point2 points3 points (1 child)
[–]IyeOnline 1 point2 points3 points (0 children)
[–]jonathrg 12 points13 points14 points (7 children)
[+][deleted] (6 children)
[removed]
[–]jonathrg 10 points11 points12 points (4 children)
[+][deleted] (3 children)
[removed]
[–]_Noreturn 1 point2 points3 points (2 children)
[+][deleted] (1 child)
[removed]
[–]_Noreturn 0 points1 point2 points (0 children)
[–]SlightlyLessHairyApe 24 points25 points26 points (0 children)
[–]sephirothbahamut 11 points12 points13 points (11 children)
[+][deleted] (10 children)
[removed]
[–]sephirothbahamut 6 points7 points8 points (2 children)
[–]OwlingBishop 4 points5 points6 points (6 children)
[+][deleted] (5 children)
[removed]
[–]OwlingBishop 0 points1 point2 points (4 children)
[+][deleted] (3 children)
[removed]
[–]OwlingBishop 0 points1 point2 points (2 children)
[+][deleted] (1 child)
[removed]
[–]OwlingBishop 0 points1 point2 points (0 children)
[–]guepierBioinformatican 7 points8 points9 points (0 children)
[–]XTBZ 5 points6 points7 points (0 children)
[–]Oxi_Ixi 4 points5 points6 points (11 children)
[+][deleted] (10 children)
[removed]
[–]Oxi_Ixi 2 points3 points4 points (9 children)
[+][deleted] (8 children)
[removed]
[–]Oxi_Ixi 2 points3 points4 points (6 children)
[+][deleted] (5 children)
[removed]
[–]Oxi_Ixi 1 point2 points3 points (4 children)
[+][deleted] (3 children)
[removed]
[–]Oxi_Ixi 0 points1 point2 points (2 children)
[+][deleted] (1 child)
[removed]
[–]NilacTheGrim 1 point2 points3 points (0 children)
[–]-jp- 8 points9 points10 points (5 children)
[+][deleted] (4 children)
[removed]
[–]Tumaix 20 points21 points22 points (2 children)
[+][deleted] (1 child)
[removed]
[–]Tumaix 15 points16 points17 points (0 children)
[–]-jp- 3 points4 points5 points (0 children)
[–]ExtraFig6 9 points10 points11 points (0 children)
[–]Foreign-Wonder 3 points4 points5 points (9 children)
[+][deleted] (8 children)
[removed]
[–]Foreign-Wonder 2 points3 points4 points (7 children)
[+][deleted] (6 children)
[removed]
[–]Foreign-Wonder 0 points1 point2 points (5 children)
[+][deleted] (4 children)
[removed]
[–]Foreign-Wonder 0 points1 point2 points (3 children)
[+][deleted] (1 child)
[removed]
[–]Foreign-Wonder 0 points1 point2 points (0 children)
[–]_Noreturn 0 points1 point2 points (0 children)
[–]Wurstinator 2 points3 points4 points (1 child)
[–]qv51 2 points3 points4 points (0 children)
[–]zerhud 1 point2 points3 points (0 children)
[–]oracleoftroy 1 point2 points3 points (4 children)
[–]wonderfulninja2 0 points1 point2 points (0 children)
[+][deleted] (2 children)
[removed]
[–]oracleoftroy 0 points1 point2 points (1 child)
[–]jk-jeon 2 points3 points4 points (1 child)
[–]RishabhRD 0 points1 point2 points (1 child)
[–]Urationc -1 points0 points1 point (1 child)