为什么我在尝试创建负大小的数组时出错?
#include <array>
int main()
{
std::array<int, -1> arr;
}
Run Code Online (Sandbox Code Playgroud)
随着-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC我没有得到任何错误.这是预期的行为吗?
我正在使用基于的二维数组std::array。
基本上代替:
MyType myarray[X_SIZE][Y_SIZE];
Run Code Online (Sandbox Code Playgroud)
我有:
std::array<std::array<MyType, Y_SIZE>, X_SIZE> myarray;
Run Code Online (Sandbox Code Playgroud)
这工作得很好,但是IMO的声明不是很可读。
有没有一种方法可以使用一些聪明的C ++模板机制来声明,所以声明可能看起来像这样?
My2DArray<Mytype, X_SIZE, Y_SIZE> myarray;
Run Code Online (Sandbox Code Playgroud) 当我发现你不能在C++ 11中使用元素作为初始化器时,我正在将一些值填充到a中constexpr std::array,然后将编译时静态良好constexpr值继续为更多值constexpr.
这是因为在C++ 14之前std::array::operator[]实际上没有标记constexpr:https://stackoverflow.com/a/26741152/688724
在编译器标志升级之后,我现在可以使用a的元素constexpr std::array作为constexpr值:
#include <array>
constexpr std::array<int, 1> array{{3}};
// Initialize a constexpr from an array member through its const operator[]
// that (maybe?) returns a const int & and is constexpr
constexpr int a = array[0]; // Works in >=C++14 but not in C++11
Run Code Online (Sandbox Code Playgroud)
但有时我想在constexpr计算中使用临时数组,但这不起作用.
// Initialize a constexpr from a temporary
constexpr int b = …Run Code Online (Sandbox Code Playgroud) 在为std::array 定义专门化是否安全std::array中,提问者询问专门化具有昂贵的默认构造函数的程序定义类型是否安全。目标是std::array使用廉价的方法来初始化 中的所有元素构造函数而不是默认构造函数来初始化 中的所有元素。
我现在并不质疑这个设计。我很好奇这种可能性,对于这个问题,我建议在聚合初始化时使用大括号省略,定义一个内部类并通过标签使用特殊的构造函数:
namespace foo {
struct cheap_tag_t {};
inline constexpr cheap_tag_t cheap_tag;
class bar {
public:
inline bar() { std::cout << "expensive ctor\n"; }
inline bar(int) { std::cout << "int ctor\n"; }
inline bar(cheap_tag_t) { std::cout << "cheap ctor\n"; }
};
} // namespace foo
Run Code Online (Sandbox Code Playgroud)
template <std::size_t N>
requires (N != 0) // let the standard array take care of N==0
struct std::array<foo::bar, N> {
struct inner_array { …Run Code Online (Sandbox Code Playgroud) 以下是在C++ 11中声明和初始化数组的8种方法g++:
/*0*/ std::array<int, 3> arr0({1, 2, 3});
/*1*/ std::array<int, 3> arr1({{1, 2, 3}});
/*2*/ std::array<int, 3> arr2{1, 2, 3};
/*3*/ std::array<int, 3> arr3{{1, 2, 3}};
/*4*/ std::array<int, 3> arr4 = {1, 2, 3};
/*5*/ std::array<int, 3> arr5 = {{1, 2, 3}};
/*6*/ std::array<int, 3> arr6 = std::array<int, 3>({1, 2, 3});
/*7*/ std::array<int, 3> arr7 = std::array<int, 3>({{1, 2, 3}});
Run Code Online (Sandbox Code Playgroud)
根据严格标准(以及即将推出的C++ 14标准),正确的是什么?什么是最常见的/使用的和那些要避免的(以及为什么)?
以下代码有效,但我想避免警告:
警告:'fitness :: vect_'应该在成员初始化列表中初始化[-Weffc ++]
当用g++ -Weffc++开关编译时:
#include <array>
template<class T, unsigned N>
class fitness
{
public:
explicit fitness(T v)
{
static_assert(N, "fitness zero length");
vect_.fill(v);
}
private:
std::array<T, N> vect_;
};
int main()
{
fitness<double, 4> f(-1000.0);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我应该忽略这个警告吗?有没有办法填写vect_构造函数初始化列表(不更改其类型)?
在C++ 11中,它允许您创建一个0长度为C的数组,std:array如下所示:
int arr1[0];
std::array arr2<int,0>;
Run Code Online (Sandbox Code Playgroud)
std::array是...(引用自cppreference):
该容器是一个聚合类型,其语义与将 C 样式数组
T[N]作为其唯一非静态数据成员的结构体具有相同的语义。
这是否意味着数组的地址始终与其第一个元素的地址相同,即data()?
#include <array>
#include <iostream>
int main()
{
std::array<int,6> x{};
std::cout << &x << "\n";
std::cout << x.data();
}
Run Code Online (Sandbox Code Playgroud)
可能的输出:
0x7ffc86a62860
0x7ffc86a62860
Run Code Online (Sandbox Code Playgroud)
如果是的话,这有什么用吗?允许以下行为吗?
int* p = reinterpret_cast<int*>(&x);
for (int i=0;i<6;++i){ std::cout << p[i]; }
Run Code Online (Sandbox Code Playgroud) 以下std::array <char, N>使用字符串文字在构造函数中初始化成员的示例不能在GCC 4.8上编译,而是使用Clang 3.4进行编译.
#include <iostream>
#include <array>
struct A {
std::array<char, 4> x;
A(std::array<char, 4> arr) : x(arr) {}
};
int main() {
// works with Clang 3.4, error in GCC 4.8.
// It should be the equivalent of "A a ({'b','u','g','\0'});"
A a ({"bug"});
for (std::size_t i = 0; i < a.x.size(); ++i)
std::cout << a.x[i] << '\n';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在第一印象,它看起来像一个GCC错误.我觉得它应该编译,因为我们可以std::array<char, N>直接用字符串文字初始化.例如:
std::array<char, 4> test = {"bug"}; //works
Run Code Online (Sandbox Code Playgroud)
我很想知道标准对此有何看法.
我需要静态地断言该类型的非constexpr数据成员的编译时大小std::array,比方说arr_,一个的非模板类是等于给定的(外部提供的)恒定。静态断言将从类内部完成,这意味着arr_可以访问,但我不能依赖任何存储的常量(也不是非类型模板参数)的大小。即,断言需要完全依赖于arr_数据成员的“一些检查” 。
如果constexpr std::array<>::size()/std::array<>::max_size()是静态成员函数(decltype(arr_)::size()/ decltype(arr_)::max_size())而不是非静态成员函数,我基本上会完成。
我有一种在成员的指向数据成员的指针上使用函数模板参数推导的工作方法arr_,但我想知道是否有更简单/更整洁的方法。
#include <array>
#include <cstddef>
// Defined/provided from elsewhere.
constexpr std::size_t kArraySize = 12U;
constexpr std::size_t kAnotherArraySize = 12U;
template <typename T, typename U, std::size_t N>
constexpr std::size_t size_of_data_member_array(std::array<T, N> U::*) {
return N;
}
class Foo {
std::array<int, kArraySize> arr_;
static_assert(size_of_data_member_array(&Foo::arr_) == kAnotherArraySize, "");
};
int main() {}
Run Code Online (Sandbox Code Playgroud)