What are make_shared, make_pair, etc called? - c++

There is a formal name for the type of functions designed to utilize template deduction to instantiate their template class counterparts. std::make_pair is a prime example of such a method. The term "helper method" comes to mind, but I recall there being a more specific term... I just can't remember it.

I'm not sure there's any more official name than "factory function". I wouldn't call it a "method" because it doesn't live on a class.
There's support for this usage in the Boost docs, as well as in this blog post by Microsoft's STL guru, Stephen T Lavavej.

Related

Is CRTP in C++ a way to express what in other languages are traits and/or ADT?

So, I'm struggling to grasp the whole CRTP thing in C++. A few (1) (2) of the rationales I found online about why should you even care to use it is that it allows to add a functionality to your code in a semi automatic way. What I mean is that I can let the compiler deduce some functionality for me, asking me only for a few small implementation.
As an example, I may want to formalize a Comparable "trait" (using a Rust word), forcing the user to provide an implementation for < and ==, and deducing all other comparisons using just these two. IIRC, this is what happens when you instantiate a std::set of a custom class (the compiler asks you for a operator<() implementation).
So, I have two question about C++'s CRTP:
In this sense, is the usage of the word "trait" appropriate? And may I even go further and say abstract data type? Is CRTP the C++ idiom to achieve this (C++ purists, forgive me)? Because to me they seem very similar: you define some basic implementation, and following some deduction rules you can get other behavior/functionality
Can I get the same thing ("trait"-like thing) by using an abstract class? If so, why should I use a CRTP instead?
Thanks!
EDIT: in the comments I have been advised that in C++ the word "trait" refers to a particular concept, which is different to the one used for instance in Rust. So I slightly change/clarify my question: is CRTP similar to Rust's traits (IIUC, specifically the #[derive]d ones)?
The CRTP idiom is a tool that injects generic functionality into a class, specifically by inserting members into it. The general, language-neutral, term for this kind of thing is a "mixin." Mechanically, "mixin" usually refers to ways of injecting members into a class without using a base class. Since the CRTP uses base classes, it does not strictly fit the definition of a mixin. But this is a matter of mechanism, not concept; a CRTP base class fulfills the general function of a mixin even if not by the usual means.
Rust traits are kind of like mixins as well. But the CRTP is not like a Rust trait for one very important reason. The whole point of Rust traits is that the class on the receiving end does not have to know that they are being given a trait. In Rust, you can force a type to have a trait interface without that type having any idea that the trait even exists.
The CRTP can't do that. A class must choose to opt-into a CRTP-based mixin interface.
So no, I would not call the CRTP a Rust trait. Indeed, the C++ concept you found called "traits" are much more like Rust traits. C++ traits define an interface that any type could adopt, and via template specialization, a user can adapt its normal interface to the traits interface. Same idea, just via a different mechanism.
The nominal similarity is not a coincidence: the makers of Rust recognized the utility of the C++ traits idiom and built a language feature specifically to facilitate it (and thus dodging all of the cruft that comes from using traits-based interfaces in C++).
In addition to #Nicol Bolas excellent answer I would like to add some comments on #[derive] traits. In rust, you can automatically implement some traits for your structs using this keyword. Here is an example taken from the link above:
#[derive(PartialEq)]
struct Foo<T> {
a: i32,
b: T,
}
The equivalent in C++ would be an automatic mixin of code, such that Foo fufills the std::equality_comparable concept. This is currently impossible because an automatic implementation would require a built-in reflection system, which C++ does not have: We would have to inject an equality operator, that checks all data members for equality, so we need to know about all data members of the type we are injecting the functionality into. There is a current proposal for built-in reflection, but even with it, it would probably be impossible to write a CRTP base class PartialEq that implements a meaningful bool operator==(X const& other) const noexcept for you. Consider the following example:
// hypothetical crtp mixin
template <typename T>
struct Foo : public PartialEq<Foo<T>> {
int a;
T b;
};
PartialEq<Foo<T>> needs to know about all datamembers of Foo<T>, but at time of the definition of PartialEq, Foo<T> is incomplete: It must be defined afterwards, because it depends on PartialEq through inheritence.
But there is yet another proposal on facilitating metaprogramming in C++ that introduces features somewhat similar to procedural macros in rust. If it gets accepted and implemented, it will be added no earlier than 2026. This proposal includes something called a metaclass, which pretty much is very close to a #[derive] trait in rust - without CRTP. The syntax would look like this:
template <typename T>
struct Foo(PartialEq) {
int a;
T b;
};
This usage scenario is even explicitly mentioned in the proposal paper, though there is a talk of a regular interface (a supertrait, in rust-speak), that injects code to satisfy the equality_comparable concept together with some other code.

C++: Enforcing template type implements a method

I have a template class and I want to know if it is possible to enforce that the template class type implements a certain interface, in particular I want to enforce that the type overloads the operator= method. In Java I would write:
public class Tree<T implements IComparable>{
public Tree(Vector<T> x){...}
}
What is the alternative in C++?
Just write the code assuming that it does. If it doesn't, it will fail to compile when the user passes in the non-conforming type. There is no need for an explicit feature here. But why on earth would you ever need an interface like IComparable for this? Templates are duck typed.
But the template error might get nasty. You can use type traits and static assert to make this simpler. However, the Standard doesn't provide a trait like this, so you'd have to write one with SFINAE.
Short answer:
No; there is no language feature to do this.
Shotish Answer:
The affect you want can be achieved using SFINAE and static asserts (asserts that are evaluated at compile time). Unfortunately this is a non trivial processes and requires a good understanding of template meta programming.
Longish Answer:
The features was suggested for the new C++11 standard, but did not make it through the review process. Read more here http://en.wikipedia.org/wiki/Concepts_(C%2B%2B) . At the current meeting (Portland Oct/12-19) Herb Sutter was suggesting that we should try for a two phase release (a minor followed by a new feature release) and concepts would be included in the first minor release. Whether this proposal is accepted will be available after the meeting.

Can I provide several defaults for a template member function?

As a huge fan of C++, there have been a question in my mind. The question is:
The classic book "Modern C++ Design" says: "The library writer cannot provide multiple default values. At best, a class template implementer can provide a single default implementation for each member function. You cannot provide several defaults for a template member function." (see "1.4 The benefit of templates")
What does the author actually mean?
To my understanding, "several defaults" is a paradox phrase. Because "several" explicitly means "multiple" and "default" implicitly means "unique".
Hope to receive some convincing explanations. Thanks in advance.
It just states what you are saying: a developer cannot establish two different values by default for a template member function.

Where can I find a good Scope Guard implementation for my C++ projects?

I just recently learned about Scope Guard C++ idiom. Unfortunately I can't find any good implementation of it.
Can anyone point me to some good and usable Scope Guard implementation in C++?
Thanks, Boda Cydo.
The original ScopeGuard class is included in this Dr. Dobb's article by Andrei Alexandrescu and Petru Marginean. A slightly improved version, with some changes from Joshua Lehrer is available here. (Lehrer's version is the one that I'm using in my projects.) It's also included in the Loki library.
Boost now has a ScopeExit library that's more powerful than ScopeGuard (since it can execute arbitrary code, whereas ScopeGuard can only call a single preexisting function).
Edit: With all of that said, a Scope Guard is really just a specific application of RAII, so you really ought to at least understand the concept of how to implement one.
ScopeGuard has been included in the Loki library (advertised in Modern C++ Design by Andrei Alexandrescu, I'm sure you've heard of this great book), and is mature enough to be used in production code, imo.
Just to be clear: We're talking about writing exception safe code using RAII.
Additional reading (on StackOverflow):
Does ScopeGuard use really lead to better code?
The Folly library (open-source from facebook) also provides an implementation (not surprising since A.A. is employed by them):
https://github.com/facebook/folly/blob/master/folly/ScopeGuard.h
I think this and the MNMLSTC implementation mentioned here are both worth consideration.
Let me offer a basic C++20 version.
#include <concepts>
#include <type_traits>
template <std::invocable Cleanup>
class [[nodiscard]] scope_guard
{
Cleanup d;
public:
scope_guard(Cleanup&& d) : d{std::forward<Cleanup>(d)} {}
scope_guard(const scope_guard&) = delete;
~scope_guard(){d();}
};
// allow construction from plain function
template <typename F>
scope_guard(F&&) -> scope_guard<std::decay_t<F>>;
Please note that unless we need to move the scope_guard around, it adds zero memory overhead over Cleanup callable, because we don't need to hold it in a resettable manner, because we don't need move constructor, because we got class template argument deduction.
A fine example of how expressive the language became. Thank you commitee!
A "Scope Guard" object is just one instance of the much broader RAII idiom.
And there is no single implementation of that. It is something a C++ programmer has to understand, not just copy/paste. Luckily, it is also pretty trivial to implement.
You create a class which represents some kind of resource. When the class is instantiated (by one of its constructors), it should acquire the resource, and throw an exception if that fails. When the class is destroyed, it should dispose of the resource, performing all the necessary cleanup.
And... that's it. You also have to handle copy constructor and assignment operator (either by cloning the resource or by making these two functions private so they're never called).
You don't need to find "a good implementation", because you're going to write dozens and dozens of different implementations yourself. They're trivial to write, and they can't easily be reused because each one wraps a different type of resource.
There's a proposal to add scope_guard to the standard library. You can read the paper, which includes a sample implementation you can copy/paste, here. See section 9.1 for the implementation.
MNMLSTC core has a modern C++11 implementation of the scope guard idiom.

"Functionoids"?

I've read the description of "functionoids" here. They look like a poor-man's version of Boost::function and Boost::bind. Am I missing something? Is there a good reason to use them if you're already using Boost?
My vote goes to tr1::function.
Functors or functionoids represent the base from which tr1/boost::function has evolved. The limit with common-interface functors is that they break the OO-paradigm since they represent different types and can only passed to template functions (unless you provide a base class from which they derive from).
Indeed by means of the type erasure technique tr1::function overcomes this limit: They are best used to implement dynamic strategy classes.
No.
Alternatively see the FQA answer here.