如何通过参数在构造函数中初始化数组?我认为type (&name)[size]
语法非常好,编译维护者可以轻松实现。标准中是否有一段禁止这种初始化?
struct Test
{
char characters_[3];
Test(char (&characters)[3]) : characters_(characters) {}
};
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
FAILED: /usr/bin/c++ -Wall -Wextra -Wconversion -pedantic -Wmissing-declarations -Wmissing-include-dirs -Wfloat-equal -std=c++11 -pg -m32 -std=gnu++11 -MMD -MT CMakeFiles/Test.dir/test.cpp.o -MF CMakeFiles/Test.dir/test.cpp.o.d -o CMakeFiles/Test.dir/test.cpp.o -c /home/user/Desktop/programms/test/Test/test.cpp
In file included from /home/user/Desktop/programms/test/Test/test.cpp:1:0:
/home/user/Desktop/programms/test/Test/test.h: In constructor ‘Test::Test(char (&)[3])’:
/home/user/Desktop/programms/test/Test/test.h:38:54: error: array used as initializer
Test(char (&characters)[3]) : characters_(characters) {}
^
FAILED: /usr/bin/c++ -Wall -Wextra -Wconversion -pedantic -Wmissing-declarations -Wmissing-include-dirs -Wfloat-equal -std=c++11 -pg -m32 -std=gnu++11 -MMD -MT CMakeFiles/Test.dir/main.cpp.o -MF CMakeFiles/Test.dir/main.cpp.o.d -o CMakeFiles/Test.dir/main.cpp.o -c /home/user/Desktop/programms/test/Test/main.cpp
In file included from /home/user/Desktop/programms/test/Test/main.cpp:4:0:
/home/user/Desktop/programms/test/Test/test.h: In constructor ‘Test::Test(char (&)[3])’:
/home/user/Desktop/programms/test/Test/test.h:38:54: error: array used as initializer
Test(char (&characters)[3]) : characters_(characters) {}
^
答案 0 :(得分:4)
也许最简单的解决方案是使用std::array
代替:
std::array<char, 3> characters;
Test(std::array<char, 3> characters) : characters(characters) {}
在C ++ 11之前,人们会将参数数组复制到构造函数体中:
Test(char (&characters)[3]) {
std::copy(characters, characters + sizeof characters, this->characters);
}
或者会使用自定义std::array
- 就像包装一样。
标准中是否有禁止此类初始化的段落?
肯定有(标准草案):
[dcl.init] / 17初始化器的语义如下。目标类型是对象或引用的类型 初始化,源类型是初始化表达式的类型。 [剪断]
(17.1) - 如果初始化程序是(非括号)braced-init-list或is = braced-init-list,则对象或引用是 list-initialized(8.6.4)。
(17.2) - 如果目的地类型是参考类型,请参阅8.6.3。
(17.3) - 如果目标类型是字符数组,则为char16_t数组,char32_t数组或 wchar_t数组,初始值设定项是字符串文字,见8.6.2。
(17.4) - 如果初始值设定项为(),则对象进行值初始化。
(17.5) - 否则,如果目标类型是数组,则程序格式错误。
[剪断]
如您所见,只有braced-init-list,字符串文字(仅限char数组)或空初始值设定项对数组有效。如果destination是数组,则不允许数组的源类型。
答案 1 :(得分:2)
在c ++ 14中,您还可以使用std::integer_sequence
和专用于初始化数组的构造函数:
#include <utility>
struct Test
{
char characters_[3];
Test(char (&characters)[3]) : Test(characters, std::make_index_sequence<3>{}) {}
private:
template <std::size_t N, std::size_t... Is>
Test(char (&characters)[N], std::index_sequence<Is...>): characters_{characters[Is]...} {}
};
int main() {
char abc[] = {'a', 'b', 'c'};
Test test(abc);
}
要在c ++ 11中应用它,您需要使用其中一个std::integer_sequence
c++11 implementations