Include std :: array in another data type at compile time?

Is there a way in C ++ 11 to pass an array of one type to another data type at compile time:

#include <iostream> #include <array> #include <type_traits> int main() { static constexpr std::array<double, 3> darray{{1.5, 2.5, 3.5}}; static constexpr std::array<int, 3> iarray(darray); // not working // Is there a way to cast an array to another data type ? return 0; } 
+7
source share
4 answers

I found a very simple solution with one variational function:

 #include <iostream> #include <array> #include <type_traits> template<typename Type, typename OtherType, std::size_t Size, typename... Types, class = typename std::enable_if<sizeof...(Types) != Size>::type> constexpr std::array<Type, Size> convert(const std::array<OtherType, Size> source, const Types... data); template<typename Type, typename OtherType, std::size_t Size, typename... Types, class = typename std::enable_if<sizeof...(Types) == Size>::type, class = void> constexpr std::array<Type, Size> convert(const std::array<OtherType, Size> source, const Types... data); template<typename Type, typename OtherType, std::size_t Size, typename... Types, class> constexpr std::array<Type, Size> convert(const std::array<OtherType, Size> source, const Types... data) { return convert<Type>(source, data..., static_cast<const Type>(source[sizeof...(data)])); } template<typename Type, typename OtherType, std::size_t Size, typename... Types, class, class> constexpr std::array<Type, Size> convert(const std::array<OtherType, Size> source, const Types... data) { return std::array<Type, Size>{{data...}}; } int main() { static constexpr std::array<double, 3> darray{{1., 2., 3.}}; static constexpr std::array<int, 3> iarray = convert<int>(darray); std::cout<<(std::integral_constant<int, iarray[2]>())<<std::endl; return 0; } 
+1
source

No, but you can do it manually quite easily using the index trick , assuming the implementation provides constexpr std::get (or equivalent to a constexpr overload operator[] ):

 #include <iostream> #include <array> #include <type_traits> // http://loungecpp.wikidot.com/tips-and-tricks%3aindices template <std::size_t... Is> struct indices {}; template <std::size_t N, std::size_t... Is> struct build_indices: build_indices<N-1, N-1, Is...> {}; template <std::size_t... Is> struct build_indices<0, Is...>: indices<Is...> {}; template<typename T, typename U, size_t i, size_t... Is> constexpr auto array_cast_helper( const std::array<U, i> &a, indices<Is...>) -> std::array<T, i> { return {{static_cast<T>(std::get<Is>(a))...}}; } template<typename T, typename U, size_t i> constexpr auto array_cast( const std::array<U, i> &a) -> std::array<T, i> { // tag dispatch to helper with array indices return array_cast_helper<T>(a, build_indices<i>()); } int main() { static constexpr std::array<double, 3> darray{{1.5, 2.5, 3.5}}; static constexpr std::array<int, 3> iarray = array_cast<int>(darray); } 

If your implementation does not provide constexpr get or operator[] , you cannot use array because there is no standard way to access the elements of a constexpr array; it is best to use your own array implementation with constexpr extensions.

Add- constexpr for the constexpr library constexpr offered to add to the standard in n3470 .

+9
source

Instead of the unreachable mess of cryptic template code that even now doesn't compile using the most commonly used C ++ compiler, and avoiding redundancy in number specifications, just use a macro:

 #include <iostream> #include <array> #include <type_traits> #define MY_VALUES( T ) {T(1.5), T(2.5), T(3.5)} int main() { static constexpr std::array<double, 3> darray = { MY_VALUES( double ) }; static constexpr std::array<int, 3> iarray = { MY_VALUES( int ) }; // Whatever... } 

This is what macros are that are good.

Just make sure that name collisions are minimized using the entire uppercase macro name and possibly a specific user prefix.


General tip: don't be too smart, keep it simple.

Keep in mind someone should support him later.

+2
source

You cannot pronounce, but you can copy:

 static constexpr std::array<double, 3> darray{{1.5, 2.5, 3.5}}; std::array<int, 3> iarray; std::copy(begin(darray), end(darray), begin(iarray)); 

Unfortunately, iarray in this case cannot be constexpr .

+1
source

All Articles