在命名空间或标头中调用 std::vector::insert 函数失败

问题描述

我试图在头文件中插入一个向量,但由于某种原因它没有编译。

#include <vector>
#include <inttypes.h>
#include <stdio.h>
    
namespace test
{
    std::vector<uint8_t> HEADERDATA{0x65,0x73,0x68,0x00,0x00};
    std::vector<uint8_t> ADDITIONALDATA{0x00,0x02,0x00};
    std::vector<uint8_t> DATA(HEADERDATA);
    DATA.insert(std::end(DATA),std::begin(ADDITIONALDATA),std::end(ADDITIONALDATA));
}

int main() {return 0;}

编译器抛出一个错误

<source>:15:1: error: 'DATA' does not name a type
   15 | DATA.insert(std::end(DATA),

但是,如果我将插入移动到主函数中,它就可以工作。

int main() 
{
    using namespace test;
    DATA.insert(std::end(DATA),std::end(ADDITIONALDATA));
}

这是 godbolt链接

有人可以解释这种行为吗?

解决方法

在函数体之外编写语句是不可能的。代码只能从初始值设定项中运行,这就是三个变量的定义有效的原因。

您可以使用内联 lambda 来创建和返回集合:

namespace test
{
    std::vector<uint8_t> HEADERDATA{0x65,0x73,0x68,0x00,0x00};
    std::vector<uint8_t> ADDITIONALDATA{0x00,0x02,0x00};
    std::vector<uint8_t> DATA([](){
        std::vector<uint8_t> data(HEADERDATA);
        data.insert(std::end(data),std::begin(ADDITIONALDATA),std::end(ADDITIONALDATA));
        return data;
    }());
}