265818 (18) [Avatar] Offline
#1
Dear Ivan,
willing to learn something useful from your recent speech at C++ Russia 2018, I tried to execute the code contained in the slides pack : http://cppconf.ru/talks/ivan-cukic " target="_blank" rel="nofollow"> http://cppconf.ru/talks/ivan-cukic

 // page 14

#include <vector>
#include <numeric>
#include <algorithm>

template <typename T>
class vector {
public:
  using value_type = T;
  void push_back(const T& value);
};

//template <typename T>
//using inner_type = typename T::value_type;

// Page 17 onwards:
// For collections that do not have a value_type nested type definition
template <typename T>
//using inner_type = decltype(*std::begin(std::declval<T>()));
using inner_type = std::decay_t<decltype(*std::begin(std::declval<T>()))>;

template <typename C, typename Val = inner_type<C>>
Val sum(const C& collection) {
  const auto begin = std::begin(collection);
  const auto end = std::end(collection);
  if (begin == end) {
    return Val{}; // or throw an exception
  }
  else {
    const auto init = *begin;
    return std::accumulate(++begin, end, init);
  }
}


template <typename ...T>
class print_types;

print_types<
inner_type<std::vector<bool>>,
inner_type<std::vector<int>>
>();

// page 25
template <typename...>
using void_t = void;

// page 27
template <typename T, typename = void_t<>>
struct has_value_type : std::false_type {};

template <typename T>
struct has_value_type<T, void_t<typename T::value_type>> : std::true_type {};


template <typename T>
auto sum(const T& collection) {
  if constexpr (has_value_type<T>()) {
    const auto begin = std::begin(collection);
    const auto end = std::end(collection);
    if (begin == end) {
      return auto{}; // or throw an exception
    }
    else {
      const auto init = *begin;
      return std::accumulate(++begin, end, init);
    }
  }
  else {

  }
}

// page 29
template <typename T>
auto inner_type_helper(T&& t) {
  if constexpr (has_value_type<T>()) {
    //return std::declval<typename T::value_type>();
  }
  else {
    return *std::begin(t);
  }
}

// page 30
template <typename T>
using inner_type_2 = decltype(inner_type_helper(std::declval<T>()));

int main() {



  return 0;
}



When compiling:

 g++ -std=c++17 void_tMetaprogramming.cpp -ovoid_tMetaprogramming
void_tMetaprogramming.cpp:43:2: error: invalid declarator before ‘(’ token
 >();
  ^


What did I miss?
Marco

Ivan Cukic (99) [Avatar] Offline
#2
Hi Marco,

The `print_types` needs to be called from inside a function - this way, you are trying to create an instance of a temporary object outside of a function which is not allowed.

Cheers,
Ivan