Skip to content

Latest commit

 

History

History
287 lines (227 loc) · 5.55 KB

287.md

File metadata and controls

287 lines (227 loc) · 5.55 KB
Info

Example

auto foo(auto&&);

int main() {
    int i{};
    const int c{};

    foo(42);       // int
    foo(i);        // int&
    foo(int{i});   // int
    foo(auto{i});  // int
    foo(auto(42)); // int
    foo(c);        // const int&
    foo(int{c});   // int
    foo(auto(c));  // int
}

https://godbolt.org/z/Thh4YohGG

Puzzle

  • Can you implement C++20/C++23 version of copy_and_sum_ts which copies and sums given parameters...?
struct copy {
    bool copied{};
    constexpr copy() = default;
    constexpr copy(const copy&) : copied{true} {}
    constexpr operator auto() const { return copied; }
};

namespace cpp20 {
   constexpr auto copy_and_sum_ts(auto&... ts); // TODO
}

namespace cpp23 {
  constexpr auto copy_and_sum_ts(auto&... ts); // TODO
}

int main() {
  constexpr copy c1, c2, c3;

  static_assert(0 == cpp20::copy_and_sum_ts());
  static_assert(1 == cpp20::copy_and_sum_ts(c1));
  static_assert(2 == cpp20::copy_and_sum_ts(c1, c2));
  static_assert(3 == cpp20::copy_and_sum_ts(c1, c2, c3));

  static_assert(0 == cpp23::copy_and_sum_ts());
  static_assert(1 == cpp23::copy_and_sum_ts(c1));
  static_assert(2 == cpp23::copy_and_sum_ts(c1, c2));
  static_assert(3 == cpp23::copy_and_sum_ts(c1, c2, c3));
}

https://godbolt.org/z/hja3qoPdx

Solutions

namespace cpp20 {

namespace detail {
constexpr auto clone(const auto & t) { return t; }
} // namespace detail

constexpr auto copy_and_sum_ts(auto &...ts) {
   return (0 + ... + detail::clone(ts));
}
} // namespace cpp20

namespace cpp23 {
constexpr auto copy_and_sum_ts(auto &...ts) {
   return (0 + ... + auto{ts});
}
} // namespace cpp23

https://godbolt.org/z/a1en6xv5f

namespace cpp20 {
   constexpr auto copy_and_sum_ts(auto&... ts) {
       return (copy{} + ... + copy{ts});
   }
}

namespace cpp23 {
  constexpr auto copy_and_sum_ts(auto&... ts) {
    return (copy{} + ... + auto{ts});
  }
}

https://cpp_tip_of_the_week.godbolt.org/z/naseW8j7n

namespace cpp20 {
   constexpr auto copy_and_sum_ts(auto&... ts){
        auto sum = 0;
        auto copier = [](auto& ts) {
          auto copy = ts;
          return copy;
        };
        return (0 + ... + copier(ts));
   };
}

namespace cpp23 {
  constexpr auto copy_and_sum_ts(auto&... ts){
      return (0 + ... + auto{ts});
  };
}

https://godbolt.org/z/Eq4ven6sf

namespace cpp11 {
   template<class... Ts>
   constexpr auto copy_and_sum_ts(Ts&... ts){
     return (0uz + ... + Ts(ts));
   }
}

namespace cpp20 {
   constexpr auto copy_and_sum_ts(auto&... ts){
     return (0uz + ... + std::remove_cvref_t<decltype(ts)>(ts));
   }
}

namespace cpp23 {
  constexpr auto copy_and_sum_ts(auto&... ts){
      return (0uz + ... + auto{ts});
  }
}

https://godbolt.org/z/YxnKzrq7b

namespace cpp20 {
  constexpr auto copy_and_sum_ts(auto&... ts) {
    return (0 + ... + [] (auto& t) { return t; }(ts));
  }
}

namespace cpp23 {
  constexpr auto copy_and_sum_ts(auto&... ts) {
    return (0 + ... + auto{ts});
  }
}

https://godbolt.org/z/h7xWjhnhx

namespace cpp20 {
constexpr auto copy_and_sum_ts(auto&... ts) {
  return (0 + ... + decltype(ts){ts});
}
}  // namespace cpp20

namespace cpp23 {
constexpr auto copy_and_sum_ts(auto&... ts) { return (0 + ... + auto{ts}); }
}  // namespace cpp23

https://godbolt.org/z/h7v16rfdv

namespace cpp20 {
   constexpr auto copy_and_sum_ts(auto&... ts) {
       return (std::remove_cvref_t<decltype(ts)>{ts} + ... + 0);
   }
}

namespace cpp23 {
  constexpr auto copy_and_sum_ts(auto&... ts) {
      return (auto{ts} + ... + 0);
  }
}

https://godbolt.org/z/xKfnhGs7b

namespace cpp20 {
   constexpr auto copy_and_sum_ts(auto&... ts){
       return (decltype(ts){ts} + ... + 0);
   }
}

namespace cpp23 {
  constexpr auto copy_and_sum_ts(auto&... ts){
      return (auto{ts} + ... + 0);
  }
}

https://godbolt.org/z/Wha7G9fEv

namespace cpp20 {
   constexpr auto copy_and_sum_ts(auto&... ts) {
       return (0 + ... + std::remove_cvref_t<decltype(ts)>{ts});
   }
}

namespace cpp23 {
  constexpr auto copy_and_sum_ts(auto&... ts) {
      return (0 + ... + auto{ts});
  }
}

https://godbolt.org/z/4Pz8Gfod5

namespace cpp20 {
   constexpr auto copy_and_sum_ts(auto&... ts) {
       constexpr auto Auto = [](auto x) {return x;};

       return (0 + ... + Auto(ts));
    }
}

namespace cpp23 {
  constexpr auto copy_and_sum_ts(auto&... ts) { return (0 + ... + auto(ts)); }
}

https://godbolt.org/z/GGG5Wf4cK

template <class T>
typename std::decay<T>::type
constexpr decay_copy (T&& t) {
    return std::forward<T>(t);
}

struct copy {
    bool copied{};
    constexpr copy() = default;
    constexpr copy(const copy&) : copied{true} {}
    constexpr operator auto() const { return copied; }
};

namespace cpp20 {
   constexpr auto copy_and_sum_ts(auto&... ts){
       return (decay_copy(ts) + ... + 0);
   }
}

namespace cpp23 {
  constexpr auto copy_and_sum_ts(auto&... ts){
      return (auto(ts) + ... + 0);
  }
}

https://godbolt.org/z/P8EYhxcx3

namespace cpp20 {
   constexpr auto copy_and_sum_ts(auto&... ts) {
       return (copy(ts).copied + ... + 0);
   }
}

namespace cpp23 {
  constexpr auto copy_and_sum_ts(auto&... ts) {
      return ( auto(ts).copied + ... + 0);
  }
}

https://godbolt.org/z/1bGs96G7M