c++ - -获取 vector 索引时出现Wsign-转换错误

标签 c++

#include <iostream>
#include <vector>
#include <stdlib.h>
#include <time.h>
int main()
{
    srand(time(NULL));
    std::vector<std::string> possible_result{"Rock", "Paper", "Scissors"};
    std::string selection{};

    std::cout << "(R)ock, (P)aper, (S)cissors: ";
    while(std::cin >> selection){
        if (selection != "R" && selection != "P" && selection != "S"){
            std::cout << "I didn't get that, try again.\n";
        } else {
            std::string election = possible_result[rand() % 3];
            std::cout << election << '\n';

        }
        std::cout << "(R)ock, (P)aper, (S)cissors: ";
    }

    return 0;
}

我正在尝试做一个简单的石头剪刀布游戏,但是在尝试编译时我得到:

“错误:从 'int' 转换为 'std::vectorstd::__cxx11::basic_string::size_type' {aka 'long unsigned int'} 可能会更改结果的符号 [-Werror=sign -转换]"

我正在使用代码块,我在其他编译器选项中有 -Wsign-conversion,当我删除该行时,程序运行正常。我不明白问题是什么,为什么它编译时没有该行?我怎样才能避免出现该错误?

最佳答案

正如评论中提到的, [] 的操作数操作std::vector容器是 size_t类型,始终无符号类型(但其位宽可能因平台而异)。因此,当您提供有符号整数作为其操作数时,编译器会生成警告(您已指示它将其转换为错误)。

正如该评论中还提到的,您可以使用 [] 上的显式强制转换来消除警告/错误。操作数,如下所示:

        std::string election = possible_result[static_cast<size_t>(rand() % 3)];

请注意,当您调用 srand() 时,您可能会收到类似的警告。 – time_t time() 返回的值call 通常是有符号类型(尽管这不是明确的 mentioned by the Standard ,IIRC),但是 srand需要一个无符号参数。

此外,当您使用 C++ 时,您应该考虑替换 rand() 的使用凭借 STL 提供的更加通用的功能,in the <random> header 。有了这些,您就可以不再需要 % 3操作(通过为生成器指定 02 的范围),并且还避免了强制转换的需要(通过为该生成器指定无符号类型)。

这是一个有效的代码示例:

#include <iostream>
#include <vector>
#include <random>
#include <ctime>  // Should really use "ctime" in place of "time.h" when using C++

int main()
{
    std::mt19937 gen(static_cast<unsigned int>(std::time(nullptr))); // Cast "time_t" to unsiged
    std::uniform_int_distribution<unsigned int> randoms(0, 2);// Set type & range (see below)
    std::vector<std::string> possible_result{ "Rock", "Paper", "Scissors" };
    std::string selection{};

    std::cout << "(R)ock, (P)aper, (S)cissors: ";
    while (std::cin >> selection) {
        if (selection != "R" && selection != "P" && selection != "S") {
            std::cout << "I didn't get that, try again.\n";
        }
        else {
            // In the call below, the random number is already "unsigned int"
            // and in the correct range...
            std::string election = possible_result[randoms(gen)];
            std::cout << election << '\n';
        }
        std::cout << "(R)ock, (P)aper, (S)cissors: ";
    }
    return 0;
}

请注意,即使在 size_t 的系统上类型相当于 unsigned long long intrandoms(gen) 的转换( unsigned int ) [] 的操作数将是“安全”促销,并且不会(或不应该)生成警告。

关于c++ - -获取 vector 索引时出现Wsign-转换错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65877299/

相关文章:

c++ - 蛮力任务的空输出

c++ - 找不到 libopecv_core.so.2.3,文件实际上不存在

c++ - 终止小数

c++循环缓冲区使用大磁盘文件

c++ - 使用 sizeof 而不是文字

c++ - Hook ExtTextOut 返回意外结果

c++ - 合并两个 Qt/C++ 项目 : redefinition errors

c++ - 为什么我可以使用非 const 变量来接收 const 函数

c++ - Stroustrup 的 RAII 和强制转换运算符 FILE*() = 矛盾?

c++ - Opencv - 如何获取图像中存在的垂直线数(线数)