The rule for determining copy constructibility is whether a non-deleted copy constructor is present. In the case of Derived, it is present. It may not be instantiatable, but that’s not what is_copy_constructible looks for.
That is what you need to know.
Now I don't follow anymore. It's a new language on top of new language on top of new language. On top of C++. On top of C.
As for everything after that, you don't need to use those features. You can still write C++ like it's '11 and be none the lesser. That's what I do. Keep it simple.
It's inevitable once you have multiple big groups of people with very different needs. And once language design and best practices has evolved from where it was when the language was originally developed.
The only ones that escape this problem aren't widely used enough to have much demand for new features or changes.
Using another language has only made me feel C++'s shortcomings more strongly than before.
Stroustrup even gave a talk about what a new C++ next language would look like and lands on many things better C languages already have implemented.
Sadly it's doubtful for gamedev to move away from C++ anytime soon. I am enjoying Vulkan+SDL in Zig on a personal project and can only hope that space of the language's community continues to grow.
For example, C++14 has introduced a digit separator in numbers, some 35 years after Ada. For me this is an extremely useful feature, because I have to use big constants from time to time, even if I hate any contributor to the C++ standard who has thought that instead of using underscore as the digit separator, like in Ada and in many languages that have followed Ada, it is a good idea to replace the underscore with the apostrophe.
There has never been any valid argument for using the apostrophe instead of the underscore. Underscore would have introduced a few subtle complications when parsing legacy programs, but that is also true for the apostrophe. Such complications could have been trivially avoided by forbidding a number to start with a separator.
Still waiting for that C+ to come out of WG14.
The day I need the performance and guarantees C++ can give me is the day I'll dive deep into Rust instead.
Yes; When you provide any of the "standard" ctors the compiler goes hands off leaving it entirely up to you to do the calls to any of the base ctors.
The article was just Raymond being surprised since as somebody else has already pointed out the api name is a bit of a misnomer.
It was my "daily driver" in the late '90s, but I would never touch it again outside of specific domains such as gaming.
kazinator•8mo ago
If it were called std::has_copy_constructor, there would be no need to write even the title of this article, let alone the body.
Also, maybe this should require a diagnostic due to it being statically obvious that it is calling a deleted constructor:
... and if we use regular non-template classes, it does!Clang:
Clang: If the program requires a diagnostic which allows it to be rejected entirely, it then doesn't matter what is_copy_constructible returned.The only reason we don't get a diagnostic is that the language plays it loose with templates, in many cases deferring type checks until instantiation.
It is possible to argue that is_copy_constructible isn't necessarily badly named, but rather foiled by templates.
unddoch•8mo ago
https://stackoverflow.com/questions/43606777/why-is-class-wi...
kazinator•8mo ago
unddoch•8mo ago
struct A { A(const volatile& A); };
as a class with a const copy constructor. Maybe someone cares?
Proper templated classes don't behave like this. If you manually define a copy constructor in a template class it has to work. And if it works only conditionally (like in many container classes) you need to add constraints on your constructors (>C++20) or derive from appropriately specialized base classes (e.g. std::_Optional_base in libstdc++).
It sucks to tell users "you're holding it wrong", but I don't think there's a way to make it simpler without breaking everything written since C++11.
kazinator•8mo ago
celrod•8mo ago
The problem with eager diagnostics and templates is that the program could define a `Base<int>` specialization that has a working copy constructor later. [0]
I think if you define an explicit instantiation definition, it should type check at that point and error. [1] I find myself sometimes defining explicit instantiations to make clangd useful (can also help avoid repeated instantiations if you use explicit declarations in other TUs).
[0] https://en.cppreference.com/w/cpp/language/template_speciali...
[1] https://en.cppreference.com/w/cpp/language/class_template.ht...
muststopmyths•8mo ago
Too many traits is my diagnosis, so I agree with "foiled by templates". Like almost any attempt to make a sane C++ codebase.
HelloNurse•8mo ago
Assumptions that something "works" in C++ are generally too nuanced and optimistic to be a good idea. Calling the test "has_copy_constructor" would at least make explicit that it is a test about what declarations a class contains, which is a very rough compile-time approximation of being copy-constructible in practice: a valid declaration is only the first step towards calling a constructor without runtime errors and other trouble.
quuxplusone•8mo ago
Ah, but then someone might ask "Why does the library report that my type has no copy constructor, when it is in fact copyable?" And then the blog post would have to be about how it's possible for a type to be copy-constructed using a constructor (or constructor template) that is not itself a copy constructor.
Of course, the existing state of C++ doesn't prevent us from having to write that blog post, either!