-符号转换错误时,获取索引向量


#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;
}

我试图做一个简单的石头,布,剪刀游戏,但当试图编译我得到:

error:从' int '转换为' std::vectorstd::__cxx11::basic_string::size_type '{也就是' long unsigned int '}可能会改变结果的符号[-Werror=sign-conversion]">

我正在使用代码块,我在其他编译器选项中有- wsign -转换,当我删除该行时,程序运行良好。我不明白问题是什么,为什么没有那行编译?怎样才能避免这个错误呢?

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

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

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

注意,你可能会收到一个类似的警告,你调用srand()-time()调用返回的time_t值通常是一个signed类型(尽管标准IIRC没有明确提到),但srand期望一个unsigned参数。

此外,当您使用c++时,您应该考虑用STL在<random>头文件中提供的更通用的函数来替换rand()。有了这些,您就可以不需要% 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)操作数的转换将是一个"安全"的提升,并且不会(或不应该)产生警告。