首页 文章

使用int值初始化vector <char>

提问于
浏览
3

我想用这个ASCII码初始化这个char向量:

vector <char> a = { 201, 187, 200, 188, 205, 186 };

我在所有6个字符中都会出现此语法错误:

从“int”到“char”的缩小转换无效:常量值不适合目标类型

但是当我使用相同的ASCII代码初始化单个char变量时:

char b = 201;

它工作正常 .

所以我意识到在向量中,由于某种原因,char类型可以接收int值直到127.从128开始出现语法错误 .

这与普通变量不同,当char类型可以接收任何int值时 .

我尝试将向量声明为unsigned char,语法错误消失 .

vector <unsigned char> a = { 201, 187, 200, 188, 205, 186 };

但是,

为什么char类型向量不能接收与char类型变量相同的int数据?

我真的很感激有人向我解释这种行为 .

2 回答

  • 8

    有两件事情在发生 .

    1
    第一个是 char 类型的默认值范围,即 implementation defined . 在大多数主要编译器中,默认值为[-128,127] . (奇怪的是,这与 signed char ,JSYK不一样!)

    MSVC和GCC都提供了将 char 视为有符号或无符号的选项 . 您可以这样做以全局解决问题 .

    但更好的是,不要假设 char 处理范围之外的任何事情[0,127] . 使用 signed charunsigned char 具体 .

    2
    第二个是你正在使用brace initialization,这要求检查文字元素值的范围拟合 .

    对于你的例子:

    std::vector <char> xs = { 201, 202 };  // compiler error
    
    char x { 201 };  // compiler error
    
    char x = 201;  // compiler warning
    

    如果你没有编译器的错误级别(你应该),那么编译器将默默地忽略该警告并分配值,即使它在技术上是无效的 .

  • 3

    没有内置的方法可以做到这一点,因为字符文字只用单引号,而数字(没有后缀)是整数 . 您可以添加L,LL,UL,ULL来制作文字长,长和无符号版本,以及其他一些用于浮点等,但字符不存在这样的后缀 .

    但是,如果您有C 11或更高版本的编译器,则可以编写自己的用户定义文字来帮助实现此目的:

    constexpr char operator "" _c(unsigned long long arg) noexcept
    {
        return static_cast<char>(arg);
    }
    
    int f()
    {
      std::vector <char> a = { 201_c, 187_c, 200_c, 188_c, 205_c, 186_c };
    }
    

    如果这不是一个选项,或者你只是不喜欢它,你总是可以写一个普通的函数来做类似的事情:

    constexpr char c(int arg) noexcept
    {
        return static_cast<char>(arg);
    }
    
    int f()
    {
      std::vector <char> a = { c(201), c(187), c(200), c(188), c(205), c(186) };
    }
    

相关问题