You can replace the last line with:
morph->search_list.emplace_back( morph->dictionary.size() - 1, 0, 0, 0 );
Thus the object is created not through brace initialization which does not allow narrowing conversion.
The narrowing conversion is from the return value of the call to size which returns std::size_t which is unsigned.
For why size() - 1 is not converted to a signed value see: C++ Implicit Conversion (Signed + Unsigned)
You can replace the last line with:
morph->search_list.emplace_back( morph->dictionary.size() - 1, 0, 0, 0 );
Thus the object is created not through brace initialization which does not allow narrowing conversion.
The narrowing conversion is from the return value of the call to size which returns std::size_t which is unsigned.
For why size() - 1 is not converted to a signed value see: C++ Implicit Conversion (Signed + Unsigned)
When and after you applied what Amir suggested, you may get an error saying something like, "this function does not take (3) arguments." To fix that you'll have to declare a constructor in the class, which you used for your vector, that takes that particular number of arguments. From what I understood when you replace push_back(); with emplace_back();the compiler thinks that you're trying to pass some variables to the constructor, which are the supposed arguments.
Warning: narrowing conversion from 'int' to 'uint8_t {aka unsigned char}' inside { } [-Wnarrowing]
c++ - Narrowing conversion from int to unsigned char - Stack Overflow
Narrowing Conversion In Codeforces Problem (
c++ - error C2397: conversion from 'int' to 'unsigned int' requires a narrowing conversion - Stack Overflow
Hi,
This is my submission to this problem. I don't understand how the narrowing conversion goes, I don't know why the first time I use std::max it says there's narrowing conversion, but why? Isn't float, double, and long double are all integers with more presicon? Or is it that if they will have decimal numbers they will "sacrifice" whole numbers?
If it's my first guess then can you help to avoid that narrowing conversion? I tried to make them all float and double numbers and still the same answer. Or is it just my code is wrong...
I hope I explained my issue well.
Thanks.
-
Edit: It seems the submission link doesn't work, so here's the code:
-
Edit: And it once, is my coding right? Am I following the best practices?
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
int n, l;
std::cin >> n >> l;
if (n == 1) {
std::cout << l / 2.0f;
}
std::vector<int> arr(n);
for (int i{}; i < n; i++) {
std::cin >> arr[i];
}
std::sort(arr.begin(), arr.end());
float min_radius{ std::max(arr[0], l - arr[n - 1]) };
int x, y;
for (int i{ 1 }; i < n; i++) {
x = arr[i - 1];
y = arr[i];
min_radius = std::max(min_radius, (y - x) / 2.0f);
x = y;
}
std::cout << min_radius;
return 0;
}And the test checks are:
Input 7 15 15 5 3 7 9 14 0 Participant's output 2.5 Jury's answer 2.5000000000 Checker comment ok found '2.500000000', expected '2.500000000', error '0.000000000'
Input 2 5 2 5 Participant's output 2 Jury's answer 2.0000000000 Checker comment ok found '2.000000000', expected '2.000000000', error '0.000000000'
Input 46 615683844 431749087 271781274 274974690 324606253 480870261 401650581 13285442 478090364 266585394 425024433 588791449 492057200 391293435 563090494 317950 173675329 473068378 356306865 311731938 192959832 321180686 141984626 578985584 512026637 175885185 590844074 47103801 212211134 330150 509886963 565955809 315640375 612907074 500474373 524310737 568681652 315339618 478782781 518873818 271322031 74600969 539099112 85129347 222068995 106014720 77282307 Participant's output 2.22582e+07 Jury's answer 22258199.5000000000 Checker comment wrong answer 1st numbers differ - expected: '22258199.5000000', found: '22258200.0000000', error = '0.0000000'
I ran into this breaking change when I used GCC. The compiler printed an error for code like this:
void foo(const unsigned long long &i)
{
unsigned int a[2] = {i & 0xFFFFFFFF, i >> 32};
}
In function
void foo(const long long unsigned int&):error: narrowing conversion of
(((long long unsigned int)i) & 4294967295ull)fromlong long unsigned inttounsigned intinside { }error: narrowing conversion of
(((long long unsigned int)i) >> 32)fromlong long unsigned inttounsigned intinside { }
Fortunately, the error messages were straightforward and the fix was simple:
void foo(const unsigned long long &i)
{
unsigned int a[2] = {static_cast<unsigned int>(i & 0xFFFFFFFF),
static_cast<unsigned int>(i >> 32)};
}
The code was in an external library, with only two occurrences in one file. I don't think the breaking change will affect much code. Novices might get confused, though.
I would be surprised and disappointed in myself to learn that any of the C++ code I wrote in the last 12 years had this sort of problem. But most compilers would have spewed warnings about any compile-time "narrowings" all along, unless I'm missing something.
Are these also narrowing conversions?
unsigned short b[] = { -1, INT_MAX };
If so, I think they might come up a bit more often than your floating-type to integral-type example.
If practical do:
enum FunctionType
{
NORMAL = 0,
RANGE = 1
};
typedef struct TableEntry
{
FunctionType value;
const char *label;
} TableEntry;
TableEntry functionTypes[] =
{
{NORMAL, "NORMAL"},
{RANGE, "RANGE"}
};
Otherwise, change the type in the struct to int, or explicitly base the enumeration on the same type as in the struct.
Btw., I the think g++ warning is unfounded and wrong, since the original code is valid C++03. Correction: As I understand it now, the diagnostic is correct, and this is a breaking change in C++11. I just couldn't believe it.
About the naming convention: those all uppercase identifiers are good for Java programmers (who are used to that convention), but in C++ they increase the chances of inadvertent text substitution. There are also the aesthetic considerations. Much win in reserving all uppercase for macros.
Usually underlying type of unscoped enumerations is int ( it can be any integral type that can represent all values of enumerators).
However I do not see any narrowing conversion because type unsigned long can represent all values of type int.
EDIT: It seems I am wrong because I found an example in the Standard that contradicts my assumption
unsigned int ui1 = {-1}; // error: narrows
So unsigned int can not be initialized by using an initializer list that contains a negative number.
So to avoid the warning the enumeration could be written as
enum FunctionType : unsigned int // or unsigned long
{
NORMAL = 0,
RANGE = 1
};
Hi Reddit,
Experienced programmer, that's new to C++ here. I'm trying to read a .txt file using C++ and store the resulting words into a vector, What I've tried so far is the following:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
int main() {
int current_char;
std::string current_word;
std::vector<std::string> words{};
std::ifstream my_file("data/The Complete Works of William Shakespeare by William Shakespeare.txt");
if (my_file.is_open()) {
while (my_file.good()) {
current_char = my_file.get();
if (std::ispunct(current_char)){
words.push_back(current_word);
current_word = "";
}
else {
current_word.push_back(current_char);
}
}
}
else {
std::cout << "File not opened" << std::endl;
}
}
The warning that I'm getting is the following Clang-Tidy: Narrowing conversion from 'int' to signed type 'char' is implementation-defined. I've googled the warning and found the clang-tidy documentation that explains the warning, however I'm unsure what I should be doing instead.
Could anyone give me an explanation of how to avoid this / what to do about it?
Thanks
Ki1103
When you declare a variable as char, it's implementation-dependent whether it's signed or unsigned. If you need to be able to store negative values, you should declare it signed explicitly, rather than relying on the implementation-defined default.
signed char c[1] = { -108 };
Since the value is legal
How do you know that? chars signedness is implementation defined. And if it's unsigned, your code is ill-formed by narrowing - §8.5.4/7:
A narrowing conversion is an implicit conversion
[…]
(7.4) — from an integer type […] to an integer type that cannot represent all the values of the original type, except where the source is a constant expression whose value after integral promotions will fit into the target type.
§8.5.1/2:
If the initializer-clause is an expression and a narrowing conversion (8.5.4) is required to convert the expression, the program is ill-formed.
However, if you need a signed char, use signed char.
signed char c[1] = {-108};
…is guaranteed to work.