是否可以在一个点声明一个const数组(可能是constexpr
),然后在另一个地方定义它,一次一个元素?
E.g。
extern constexpr int myArray[100];
myArray[0] = myConstexprFunction(0);
myArray[1] = myConstexprFunction(1);
// ...
myArray[100] = myConstexprFunction(100);
我想做的事情需要这样的事情。也许可以使用以下内容:http://b.atch.se/posts/constexpr-counter/
但是如果这种技术在下一个C ++标准中是非法的(我希望不是),我想使用更安全的技术。
[编辑]如何放宽一些要求..让我们说我想做这样的事情:
constexpr int myConstExprFunction(int arg) { return arg + 100;}
// other code...
constexpr int a = myConstExprFunctionBegin(10);
constexpr int b = myConstExprFunction(20);
constexpr int c = myConstExprFunction(30);
constexpr int d = myConstExprFunctionEnd(40);
我想要的是myConstExprFunctionEnd能够使用前面函数创建的值生成最终数组。 一切都在编译时。当然。
[EDIT2]非常欢迎C ++ 11解决方案
答案 0 :(得分:4)
constexpr
声明可以在编译时评估函数或变量的值。
所以你可以将它与数组一起使用的唯一方法就是:
constexpr int myArray[100]{1 , 2 , 3 ,.........};
等语句
myArray[0] = myConstexprFunction(0);
只能在运行时进行评估。所以它不可能。
答案 1 :(得分:4)
最近的C ++ constexpr
的要求非常宽松,所以你可以写一下:
// requires C++17:
constexpr auto myArray = [] {
std::array<int, 100> result {};
for (size_t i = 0; i < 100; ++ i) {
result[i] = i * i;
}
return result;
}();
注意我使用了std::array<int, 100>
而不是int[100]
,因为函数无法返回C数组。
以上代码需要C ++ 17,原因有两个:
constexpr
lambda operator[]
不是constexpr
醇>
使用单独的constexpr函数可以轻松解决问题1。问题2只能通过定义自己的数组包装器来解决。
// requires C++14:
template <typename T, size_t n>
struct ConstexprArray {
T data[n];
constexpr ConstexprArray() : data{} {}
constexpr T& operator[](size_t i) { return data[i]; }
};
constexpr auto initialize_my_array() -> ConstexprArray<int, 100> {
ConstexprArray<int, 100> result {};
for (size_t i = 0; i < 100; ++ i) {
result[i] = i * i;
}
return result;
}
constexpr auto myArray = initialize_my_array();
答案 2 :(得分:3)
如果你想声明constexpr
一个数组并使用constexpr
函数初始化它的值......我能想到的最好的方法是将数组包装在struct / array中并通过委托初始化它构造
以下是一个完整的C ++ 14示例
#include <utility>
#include <iostream>
constexpr int myConstexprFunction (int i)
{ return i << 1; } // return 2*i
template <std::size_t S>
struct wrapArray
{
int const myWrappedArray[S];
template <int ... Is>
constexpr wrapArray (std::integer_sequence<int, Is...> const &)
: myWrappedArray { myConstexprFunction(Is)... }
{ }
constexpr wrapArray ()
: wrapArray(std::make_integer_sequence<int, S>())
{ }
};
int main ()
{
constexpr wrapArray<100> wa100;
for ( auto i : wa100.myWrappedArray )
std::cout << i << ", ";
std::cout << std::endl;
}
如果您需要C ++ 11代码,则必须替换std::integer_sequence
和std::make_integer_sequence()
。这并不难。
答案 3 :(得分:3)
查看您的编辑,我只回答 no ,因为编译器无法将一组变量转换为数组。它只是不那样工作。在C ++中没有任何构造可以采取一堆声明,删除它们并用另一个声明替换它。源代码预处理器或生成器可能能够允许您寻找的语法。
如果您对不需要外部工具的解决方案感兴趣,可以创建一个返回数组的constexpr
函数:
constexpr auto makeMyArray() {
std::array<int, 100> myArray;
myArray[0] = myConstExprFunction(10);
myArray[1] = myConstExprFunction(20);
// ...
return myArray;
}
然后,初始化你的数组:
constexpr auto myArray = makeMyArray();
答案 4 :(得分:1)