Oct 7, 2017

[C++][Cppcon 2017] Modern C++ Interfaces

Reference:
http://www.stevedewhurst.com/
https://www.youtube.com/watch?v=PFdWqa68LmA

Policy-based design: Modern C++ Design, Andrei Alexandrescu

SFINAE becomes more and more essential due to compile time meta-programming.

C++ has become so complex that we can use it easily.

Most good bugs are team efforts.

Increased language complexity is not an advantage in itself.
However, it leads to greater expressiveness than would a less complex language.
Simplicity is an emergent property.


Universal reference as copy constructor bug

http://ericniebler.com/2013/08/07/universal-references-and-the-copy-constructo/
https://eli.thegreenplace.net/2014/perfect-forwarding-and-universal-references-in-c/
https://akrzemi1.wordpress.com/2013/10/10/too-perfect-forwarding/


// write this once and put it somewhere you can
// reuse it
template<typename A, typename B>
using disable_if_same_or_derived =
    typename std::enable_if<
        !std::is_base_of<A,typename
             std::remove_reference<B>::type
        >::value
    >::type;

template<typename T>
struct wrapper
{
    T value;
    template<typename U, typename X =
        disable_if_same_or_derived<wrapper,U>>
    wrapper( U && u )
      : value( std::forward<U>(u) )
    {}
};

The complexity of the language has forced us to become better programmers and designers

Use the force, <type_traits>

Syntax matters


template<typename T>
using IsMonad = typename enable_if<is_monad<T>::value>::type;

template<typename T, typename = IsMonad<T>>
void monad_input(T const& t);

Transparent function objects

e.g:
Used by, e.g set::lower_bound

template<typename T, typename Comp, ...>
class set{
public:
    iter lower_bound(const T& key);
    template <typename Key,
                typename = typaneme Comp::is_transparent>
    iter lower_bound(const Key& key);
};


Distributed Organic Interfaces

The interface to set is modified based on self-identified properties of its comparator.

Who's in charge of the interface?
  •     The set advertieses the availability of an augmented interface.
  •     The comparator may choose to enable that interface.
Alternatively,
  •     The comparator advertieses its transparency.
  •     The set is designed to take advantage of that transparency.
Alternatively,
  •     A user notices the potential combination and connects the components.
Compose (e.g:)
template<template<typename...> class ... Preds>
struct Compose {
    template<typename T>
    static constexpr auto eval() {
        auto results = {Preds<T>::value...};
        auto result = true;
        for ( auto el : results)
            result &= el;
        return result;
};

Or even neater (variable template):

template <typename T, template<typename> class... Ts>
inline constexpr auto staisfies_all = 
    (... && Ts<T>::value);

template <typename T, template<typename> class... Ts>
inline constexpr auto staisfies_some = 
    (... || Ts<T>::value);

template <typename T, template<typename> class... Ts>
inline constexpr auto staisfies_none = 
    (... && !Ts<T>::value);

And monoid:

template <typename T>
inline constexpr auto satisfies_my_needs
    = satisfies_all<T, is_signed, is_pod> &&
        satisfies_none<T, is_polymorphic, is_array>;

static_assert(satisfies_my_needs<T>, "Ha! Not satisfied!")

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.