the following code does not compile gcc 5.2 (c++14). does compile clang 3.6 (c++14). (original code can found here)
#include <cstddef> #include <algorithm> #include <type_traits> #include <utility> template <typename t> class aggregate_wrapper; template <typename t, std::size_t n> class aggregate_wrapper<t[n]> { public: using array = t[n]; template <typename... ts, typename = decltype(array{std::declval<ts>()...})> aggregate_wrapper(ts&&... xs) : arr_{std::forward<ts>(xs)...} { // nop } aggregate_wrapper(const array& arr) { std::copy(arr, arr + n, arr_); } aggregate_wrapper(array&& arr) { std::move(arr, arr + n, arr_); } operator t* () { return arr_; } operator const t* () const { return arr_; } constexpr std::size_t size() const { return n; } private: array arr_; }; int main() { aggregate_wrapper<int[3]> arr; static_assert(arr.size() == 3, ""); }
the error message produced is
main.cpp: in function 'int main()': main.cpp:44:3: error: non-constant condition static assertion static_assert(arr.size() == 3, ""); ^ main.cpp:44:25: error: call non-constexpr function 'constexpr std::size_t aggregate_wrapper<t [n]>::size() const [with t = int; long unsigned int n = 3ul; std::size_t = long unsigned int]' static_assert(arr.size() == 3, ""); ^ main.cpp:34:25: note: 'constexpr std::size_t aggregate_wrapper<t [n]>::size() const [with t = int; long unsigned int n = 3ul; std::size_t = long unsigned int]' not usable constexpr function because: constexpr std::size_t size() const { ^ main.cpp:34:25: error: enclosing class of constexpr non-static member function 'constexpr std::size_t aggregate_wrapper<t [n]>::size() const [with t = int; long unsigned int n = 3ul; std::size_t = long unsigned int]' not literal type main.cpp:10:7: note: 'aggregate_wrapper<int [3]>' not literal because: class aggregate_wrapper<t[n]> { ^ main.cpp:10:7: note: 'aggregate_wrapper<int [3]>' not aggregate, not have trivial default constructor, , has no constexpr constructor not copy or move constructor
any ideas? should code compile according standard?
or make existing variadic constructor serve constexpr
constructor perform default construction:
template <typename... ts, typename = decltype(array{std::declval<ts>()...})> constexpr // <---- add aggregate_wrapper(ts&&... xs) : arr_{std::forward<ts>(xs)...} { // nop }
Comments
Post a Comment