【问题标题】:How to use a default argument for std::array? "array must be initialized with a brace-enclosed initializer"如何为 std::array 使用默认参数? “数组必须用大括号括起来的初始化程序初始化”
【发布时间】:2013-10-09 17:43:07
【问题描述】:

我的构造函数采用std::array。我试图给它一个默认值,但是在没有参数的情况下调用构造函数会给出这个错误:

$ g++ -std=c++11 -Wall -Werror -Wextra -pedantic-errors test.cpp Position.cpp -o test
test.cpp: In function ‘int main()’:
test.cpp:14:29: error: array must be initialized with a brace-enclosed initializer
  Position *y = new Position();
                             ^
test.cpp:14:29: error: too many initializers for ‘std::array<unsigned char, 8ul>’

行号不同。这是我的代码:

// test.cpp
int main() {
    Position *x = new Position({1,1,1,1,1,1,1,1}); // works
    Position *y = new Position(); // does not work
}

// Position.cpp
#include <cstdint>
#include <array>
#include "Position.h"
Position::Position( std::array<uint8_t,8> columns_ ) {
    columns = columns_;
}

// Position.h
#ifndef POSITION_H
#define POSITION_H
#include <array>
class Position {
    public:
    Position( std::array<uint8_t,8> = {0,0,0,0,0,0,0,0} );
    private:
    std::array<uint8_t,8> columns;
};
#endif

我做错了什么?

【问题讨论】:

  • 为什么不重载Position::Position()
  • @cpp 他不想那样做。他想要 constructor 的参数的默认值,而不是 main.
  • @Adam,我知道,我参考了这个问题的答案,据说,不可能通过值将完整的内存块作为参数传递给函数,并且它与 main() 无关。
  • @cpp 如果你被命名为cpp11,你就不会这么说。

标签: c++ c++11 constructor default-value stdarray


【解决方案1】:

你需要重复输入:

Position( std::array<uint8_t,8> = std::array<uint8_t,8>{0,0,0,0,0,0,0,0} );

虽然这(或使用双括号)有效,但当采用默认值时,它会在每个调用方的一方创建一个副本。重载的构造函数可以避免这种代码膨胀,因此我建议优先使用重载而不是默认参数。

【讨论】:

  • 这些副本没有被编译器优化掉?因为在调用站点,编译器知道是否提供了默认参数。
  • @TemplateRex 如果方法的实现在不同的翻译单元中结束,编译器就没有机会优化它。 (也许,只是也许,LTO 可以来拯救,但我永远不会依赖它)
  • 好的,但是对于 STL 标头(带有隐藏的分配器等等)和其他仅标头的代码,这个问题不适用,对吗?
  • @TemplateRex 即使这样也不完全正确。仅仅因为编译器可以优化它并不意味着它实际上可以。此外,在某些情况下,语言规则使优化内容变得更加困难。在重载中,您甚至可以进一步简化实现。但总的来说,它总是在代码简单性、可维护性、效率和代码大小之间进行权衡。对实际情况的了解和认识使您能够做出明智的决定 - 但这始终是一个决定,我不相信一刀切的解决方案。
【解决方案2】:

运行第二种情况需要双括号:

Position( std::array<uint8_t,8> = {{0,0,0,0,0,0,0,0}} );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-18
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 2016-12-20
    相关资源
    最近更新 更多