获取向量

时间:2021-01-24 23:56:16

标签: 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,当我删除该行时程序运行良好。我不明白问题是什么,为什么没有那行就编译?我怎样才能避免出现该错误?

1 个答案:

答案 0 :(得分:0)

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

正如该评论中所述,您可以使用 [] 操作数上的显式强制转换使警告/错误静音,如下所示:

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

请注意,您可能会在调用 srand() 时收到类似警告 - time_t 调用返回的 time() 值通常是签名类型(虽然这不是明确的 mentioned by the Standard,IIRC)但是 srand 需要一个 unsigned 参数。

此外,当您使用 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 int 的系统上,randoms(gen)unsigned int ([]) 操作数的转换将是“安全”的促销活动,不会(或不应该)生成警告。