Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Static duck typing in C++

C++ has some sort of duck typing for types given by template parameters. We have no idea what type DUCK1 and DUCK2 will be, but as long as they can quack(), it will compile and run:

template <class DUCK1, class DUCK2>
void let_them_quack(DUCK1* donald, DUCK2* daisy){
  donald->quack();
  daisy->quack();
}

But it's a bit inconvenient to write. When I do absolutely not care what actual types DUCK1 and DUCK2 are but rather want to fully use the idea of duck typing, then I would like to have something sligthly different than above:

  1. I'd like to omit writing a template parameter list that is repetitive and mostly meaningless (Just imagine what would happen if there are 7 ducks...)
  2. I'd like to make it a bit more explicit that the types are never used and that it's only the interface that matters.
  3. I'd like to have sort of an interface annotation/check. Make somehow clear what interface is expected behind the type. (That's, however, a bit in contrast of duck typing.)

Does C++ offer any features to achieve one or more of the 3 ideas?

(I know that virtual inheritance is the method of choice in most cases to implement such patterns, but the question here is specifically about the case of static polymorphism.)

like image 350
Michael Avatar asked Apr 27 '16 12:04

Michael


People also ask

What is static duck typing?

Static duck typing is similar to structural typing that some static typed languages (Scala, F#) support. Structural typing allows for some compile-time checks, not on types but on the supported methods/attributes. Structural typing may be seen as a compiler-enforced subset of duck typing.

What is duck typing?

Duck typing is a concept related to dynamic typing, where the type or the class of an object is less important than the methods it defines. When you use duck typing, you do not check types at all. Instead, you check for the presence of a given method or attribute.

What is the difference between static and dynamic typing duck typing?

Structural type systems Structural typing is a static typing system that determines type compatibility and equivalence by a type's structure, whereas duck typing is dynamic and determines type compatibility by only that part of a type's structure that is accessed during run time.

Is duck typing the same as dynamic typing?

Introduction. Duck Typing is a term commonly related to dynamically typed programming languages and polymorphism. The idea behind this principle is that the code itself does not care about whether an object is a duck, but instead it does only care about whether it quacks.


Video Answer


2 Answers

Concerning questions 1 and 2: since C++14 you can omit explicit template <typename ... boilerplate and use auto, but only in lambdas:

auto let_them_quack = [] (auto & donald, auto & daisy){
    donald.quack();
    daisy.quack();
};

(yes, I prefer references to pointers). GCC allows to do so in usual functions as an extension.

For the question 3, what you are talking about are called concepts. They existed in C++ for a long time, but only as a documentational term. Now the Concepts TS is in progress, allowing you to write something like

template<typename T>
concept bool Quackable = requires(T a) {
    a.quack();
};

void let_them_quack (Quackable & donald, Quackable & daisy);

Note that it is not yet C++, only a technical specification in progress. GCC 6.1 already seems to support it, though. Implementations of concepts and constraints using current C++ are possible; you can find one in boost.

like image 143
lisyarus Avatar answered Oct 21 '22 09:10

lisyarus


I'd like to omit writing a template parameter list that is repetitive and mostly meaningless (Just imagine what would happen if there are 7 ducks...)

For that you could use variadic templates and do something like the following:

template<typename DUCK>
void let_them_quack(DUCK &&d) {
  d.quack();
}

template<typename DUCK, typename... Args>
void let_them_quack(DUCK &&d, Args&& ...args) {
  d.quack();
  let_them_quack(std::forward<Args>(args)...);
}

Live Demo

like image 38
101010 Avatar answered Oct 21 '22 07:10

101010