C++ 在编译时将std::数组强制转换为其他数据类型?

C++ 在编译时将std::数组强制转换为其他数据类型?,c++,arrays,casting,c++11,compile-time,C++,Arrays,Casting,C++11,Compile Time,在C++11中,是否有一种方法可以在编译时将一种类型的数组强制转换为另一种数据类型: #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&g

在C++11中,是否有一种方法可以在编译时将一种类型的数组强制转换为另一种数据类型:

#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;
}
#包括
#包括
#包括
int main()
{
静态constexpr std::数组darray{{1.5,2.5,3.5};
静态constexpr std::array(darray);//不工作
//有没有办法将数组强制转换为另一种数据类型?
返回0;
}

您不能强制转换,但可以复制:

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));
staticconsteprstd::数组darray{{{1.5,2.5,3.5};
阵列射线;
复制(开始(darray)、结束(darray)、开始(iarray));

不幸的是,在这种情况下,
iarray
不再是
constexpr

否,但您可以使用手动操作,前提是实现提供了
constexpr
std::get
(或相当于
操作符[]
重载):

#包括

包含了不可维护的模糊模板代码,这些模板代码甚至不在当前使用最常用的C++编译器编译,并且避免了在数字规格中的不好的冗余,只需使用宏:

#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...
}
#包括
#包括
#包括
#定义我的_值(T){T(1.5),T(2.5),T(3.5)}
int main()
{
静态constexpr std::数组darray={MY_值(double)};
静态constexpr std::array={MY_值(int)};
//不管怎样。。。
}
这是宏所擅长的

只需确保使用全大写宏名称,以及一些自定义前缀,将名称冲突的可能性降至最低


一般建议:不要太聪明,保持简单


请记住,以后必须有人对其进行维护。

我发现了一个非常简单的单变量函数解决方案:

#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;
}
#包括
#包括
#包括
模板
constexpr std::array convert(const std::array source,const type…data);
模板
constexpr std::array convert(const std::array source,const type…data);
模板
constexpr std::array convert(const std::array source,const type…data)
{
返回转换(源、数据…、静态转换(源[sizeof…(数据)]);
}
模板
constexpr std::array convert(const std::array source,const type…data)
{
返回std::数组{{data…};
}
int main()
{
静态constexpr std::数组darray{{1,2,3};
静态constexpr std::array=convert(darray);

std::coutI’d’d’d’d’d’d’d’d’t’t’t’t’t’t’t’t’t’t’t’t’t’t’t’t’t’t’t’t’t’t’t’t’t’t’t’t’t’t’t’t’t’t’t’t’constexpr作为一个扩展,您可以创建一个constexpr函数来创建您的iarray。@即使使用std::get,MarcGlisse?检查标准,get的数组重载上没有constexpr。@Marc我认为您可以作弊并重新解释\u cast(&darray)[I]
但这对编写没有帮助,只能用于阅读。由于赋值从来都不是一个常量表达式,因此无法赋值,即使在递归的
constexpr
函数中也是如此。只有几行空行(并将函数体放在单独的一行上)定义之间的差异将使可读性增加数千倍……此外,对于
std::array
,是
std::get
constexpr
?这与cppreference.com无关。@KonradRudolph欢呼,已修复并讨论过。为了清晰起见,请随意编辑。您可以使用模板转换运算符技巧来消除传递的需要ODE >代码< >代码> ARAYYXCAST 。我宁愿用STUD::数组来删除简单的int;-@ @ Balki: <代码> CONTXPRP</CUC>是无声的IIRC。问题特别要求在编译时进行转换。@本,但这在当前的C++标准中是不可能的(参见EcMuURE的回答和注释),这是第二个最好的方法。+1尽管如ecatmur的回答中所述,
operator[]
必须声明
constepr
,以使其正常工作,但不幸的是,当前标准中缺少了这一点(尽管对于gcc,它是
constepr
)。
#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;
}