我尝试了以下代码:
int main()
{
int x {23.22};
}
Run Code Online (Sandbox Code Playgroud)
其中包括需要缩小的初始化,但代码编译正常,没有任何错误或警告.另一方面,以下代码给出错误:
int main()
{
int x[]{23.22};
}
Run Code Online (Sandbox Code Playgroud)
我发现了一个bug还是什么?
PS:我目前正在使用GCC 4.5.0
我正在编写一个单元测试,检查一些预期数组的二进制数据.有问题的预期数组只是一些字节序列,具体并不重要:
char expected[] = {0x42, 0xde, 0xad, 0xbe, 0xef};
Run Code Online (Sandbox Code Playgroud)
这在C++中编译得很好,但是对于C++ 11,这会在缩小转换时发出警告.我编译-Werror因为警告很重要,所以这行不为我编译.据我所知,char没有文字后缀,所以看来我必须这样做:
char expected[] = {static_cast<char>(0x42), static_cast<char>(0xde), ... };
Run Code Online (Sandbox Code Playgroud)
这对我来说似乎很笨拙.有没有更好的方法来构造这个字符数组?(删除-Werror或添加之外-Wno-narrowing).
在我的代码库中,我经常使用以下语法初始化数组或向量(如果是字节):
uint16_t foo = 0xAB, bar = 0xCD
// bytes = { 0xA, 0xB, 0xC, 0xD }
std::array<uint8_t, 4> bytes = {{
foo >> 8,
foo & 0x00FF,
bar >> 8,
bar & 0x00FF
}};
Run Code Online (Sandbox Code Playgroud)
我从clang ++中得到以下错误:
error: non-constant-expression cannot
be narrowed from type 'int' to 'value_type' (aka 'unsigned char') in initializer list [-Wc++11-narrowing]
foo >> 8,
^~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
编译器建议我添加一个static_cast来消除错误.我知道演员会工作,但我想知道是否有可能避免演员表并保持语法优雅,因为它已经存在?
谢谢您的帮助.
在C ++核心原则有一个narrow抛出如果转换改变了值施放。查看该库的microsoft实现:
// narrow() : a checked version of narrow_cast() that throws if the cast changed the value
template <class T, class U>
T narrow(U u) noexcept(false)
{
T t = narrow_cast<T>(u);
if (static_cast<U>(t) != u)
gsl::details::throw_exception(narrowing_error());
if (!details::is_same_signedness<T, U>::value && ((t < T{}) != (u < U{}))) // <-- ???
gsl::details::throw_exception(narrowing_error());
return t;
}
Run Code Online (Sandbox Code Playgroud)
我不明白第二个if。它会检查什么特殊情况static_cast<U>(t) != u?为什么还不够?
为了完整性:
narrow_cast只是一个static_cast:
// narrow_cast(): a searchable way to do …Run Code Online (Sandbox Code Playgroud) 我正在尝试从sourceforge 编译hosts3d,它确实可以编译,但会生成几个缩小错误。我不知道如何解决这个问题,但任何帮助将不胜感激。我怀疑我可以下载以前版本的编译器,我可能最终会这样做,但现在...... c++11
g++ -Wall -O2 -c -o src/glwin.o src/glwin.cpp src/glwin.cpp: 在成员函数 'int MyGLWin::AddInput(int, int, unsigned int, int, const char*, bool) 中': src/glwin.cpp:983:147:警告:在 { } 内将 'max' 从 'int' 缩小到 'unsigned int' 的转换在 C++11 中格式不正确 [-Wnarrowing] glin_obj glin = {GLWIN_INPUT ,lastWin,lower,names++,left,top,cwidth,strlen(text),(strlen(text)>cwidth?strlen(text)-cwidth:0),max};
//create input object, return name of input object
int MyGLWin::AddInput(int left, int top, unsigned int cwidth, int max, const char *text, bool lower)
{
if (!lastWin) return -1; //check parent window object exists
glin_obj glin = {GLWIN_INPUT, …Run Code Online (Sandbox Code Playgroud) 我尝试使用gcc和C++11启用以下代码编译:
unsigned int id = 100;
unsigned char array[] = { id % 3, id % 5 };
Run Code Online (Sandbox Code Playgroud)
我收到这些警告:
缩小'(id%3u)'从'unsigned int'到{}内的'unsigned char'的转换[-Wnarrowing]
有没有办法帮助编译器发现id%3的结果符合unsigned char?
有人知道为什么编译时没有警告吗
int main()
{
const int i = 1024;
std::initializer_list<size_t> i_l = { i }; // no warning
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但不
int main()
{
const int i = pow(2,10);
std::initializer_list<size_t> i_l = { i }; // warning
return 0;
}
Run Code Online (Sandbox Code Playgroud)
警告:
non-constant-expression cannot be narrowed from type 'int' to 'unsigned long' in initializer list [-Wc++11-narrowing]
std::initializer_list<size_t> i_l = { i }; i_l = i_l; // warning
Run Code Online (Sandbox Code Playgroud) 我目前正在尝试改进现有代码的类型.我的代码看起来大致如下:
/* dispatcher.ts */
interface Message {
messageType: string;
}
class Dispatcher<M extends Message> {
on<
MessageType extends M["messageType"],
SubMessage extends M & { messageType: MessageType }
>(
messageType: MessageType,
handler: (message: SubMessage) => void
): void { }
}
/* messages.ts */
interface AddCommentMessage {
messageType: "ADD_COMMENT";
commentId: number;
comment: string;
userId: number;
}
interface PostPictureMessage {
messageType: "POST_PICTURE";
pictureId: number;
userId: number;
}
type AppMessage = AddCommentMessage | PostPictureMessage;
/* app.ts */
const dispatcher = new Dispatcher<AppMessage>();
dispatcher.on("ADD_COMMENT", …Run Code Online (Sandbox Code Playgroud) 背景:我正在编写一个包装器类型,例如Either<A, B>,并且我想return {some, args};从返回的函数中工作,Either<A, B>当它从返回的函数中工作时,A或B. 不过,我也希望,当检测到两个 A及B可能与初始化{some, args},并产生一个错误,从模糊保护用户。
为了检测是否T可以从某些参数初始化类型,我尝试编写这样的函数:
template<typename T, typename... Args>
auto testInit(Args&&... args) -> decltype(T{std::forward<Args>(args)...});
// imagine some other fallback overload here...
Run Code Online (Sandbox Code Playgroud)
我认为表达式testInit<T>(some, args)应该在有效的时候T{some, args}有效——在下面的代码中,初始化auto x = MyType{1UL, 'a'};工作,并且这个测试也通过了:
struct MyType {
MyType(size_t a, char b) {}
};
auto x = MyType{1UL, 'a'}; // ok
static_assert(std::is_same<MyType, decltype(testInit<MyType>(1UL, 'a'))>::value, ""); // ok
Run Code Online (Sandbox Code Playgroud)
但是,当我们从 中添加构造函数时 …
我不明白这一点:
const VALUES = {
name: "name",
age: "age",
address: "address",
};
export function getVal(key: string) {
if (key in VALUES) {
// Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ name: string; age: string; address: string; }'.
// No index signature with a parameter of type 'string' was found on type '{ name: string; age: string; address: string; }'.ts(7053)
return VALUES[key];
}
return "";
}
Run Code Online (Sandbox Code Playgroud)
条件明确地使成为true 分支中的key键之一。 …