非常简短
如何创建一个包含所有位的无符号常量?
...您可以使用{} s初始化字段,
......没有得到GCC 4.7.2的警告.
以下不满意:
struct U { unsigned ufield; };
struct Uc { unsigned char ufield; };
struct ULL { unsigned long long ufield; };
struct U32 { unsigned ufield; };
struct U64 { uint64_t ufield; }
typedef
//any of the above U Uc ULL U32 U64, we will arbitrarily choose:
U Ueg;
// somewhere far away
Ueg u = {-1}; // well defined by C standard, GCC 4.7.2 -Wnarrowing warning
Ueg u = {~0U}; // finit …Run Code Online (Sandbox Code Playgroud) 我以为括号初始化不允许缩小。但是为什么int const允许char括号初始化?
int value1 = 12;
char c1{value1}; // error! no narrowing
const int value2 = 12;
char c2{value2}; // why is this fine?
Run Code Online (Sandbox Code Playgroud)
在Godbolt上看到它。
我在"C++编程语言"第4版中学习了大括号分隔初始化器.>第2章:C++之旅:基础知识.
我引用下面的书.
=表格是传统的并且可以追溯到C,但是如果有疑问,请使用通用{} -list表单(第6.3.5.2节).如果不出意外,它可以帮助您避免丢失信息的转换(缩小转化次数;§10.5):
Run Code Online (Sandbox Code Playgroud)int i1 = 7.2; // i1 becomes 7 int i2 {7.2}; // error : floating-point to integer conversion int i3 = {7.2}; // error : floating-point to integer conversion (the = is redundant)
但是,我无法重现这些结果.
我有以下代码.
#include <iostream>
int main()
{
int i1 = 7.2;
int i2 {7.2};
int i3 = {7.2};
std::cout << i1 << "\n";
std::cout << i2 << "\n";
std::cout << i3 << "\n";
}
Run Code Online (Sandbox Code Playgroud)
当我编译并运行它时,我没有得到任何错误.我收到警告,std=c++11但没有错误.
$ g++ init.cpp
init.cpp: In function …Run Code Online (Sandbox Code Playgroud) 以下程序使用gcc 4.8.1编译时没有错误或警告
-Wall -std=c++11:
template<unsigned N>
struct A{};
int main(){
A<1-2> a;
(void)a;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用相同选项的clang 3.3会出现此错误:
错误:非类型模板参数的计算结果为-1,不能缩小为'unsigned int'类型[-Wc ++ 11-narrowing]
根据这个问题,看起来gcc的现行政策只是为了缩小标准指示错误的转换,以及clang给出指示错误的警告.但在这种情况下,gcc甚至没有发出警告.
标准第8.5.4/7节(在该问题中再现)中缩小转换错误的例子都没有涵盖非类型模板参数缩小转换的情况,但是§14.3.2/ 5标准说:
对于积分或枚举类型的非类型模板参数,将应用转换常量表达式(5.19)中允许的转换.
并且§5.19/ 3说:
T类型的转换常量表达式是一个文字常量表达式,隐式转换为类型T,其中隐式转换(如果有)在文字常量表达式中是允许的,而隐式转换序列仅包含用户定义的转换,lvalue-to- 除缩小转化次数之外的右值转换(4.1),整数促销(4.5)和积分转换(4.7)(8.5.4)
(我的重点).
在我看来,这意味着即使按照自己的标准,gcc也是错误的,在这种情况下根本没有诊断出变窄的转换.我读得对吗?是否存在基于标准的反驳论点?
我更多的感觉只是好奇心问这个问题.在递归TMP设置中,clang在这种情况下的错误诊断将查明无符号非类型模板参数通过0的错误,而从gcc获得的所有错误都是"超出最大模板实例化深度".
我想在一个函数中链接 2 个泛型类型,并通过检查其中之一来对这两种类型使用缩小范围。这样做的正确方法是什么?
type A = 'A';
type B = 'B';
type AB = A | B
type ComplexType<T> = {value: T}
const f = (next: ComplexType<A>) => {}
const builder = <T extends AB>(value: T) => (next: ComplexType<T>) => {
if (value === 'A') {
f(next) // expect next is ComplexType<A> but got error
}
}
Run Code Online (Sandbox Code Playgroud) 在它的当前版本中,是否可以在访问它的API时使用Bing的"Narrow By Date"功能?
我找不到任何关于如何缩小结果的信息,只显示"过去24小时"或"过去一周"的结果(依此类推).
网站/文档并不完全清楚我能做什么和不能做什么,以及如何做.你们中的任何人都知道这是否可能?
我可以在其高级搜索关键字页面上看到,您可以在此处使用其他缩小功能(区域,语言,进纸等):http://onlinehelp.microsoft.com/en-ca/bing/ff808421.aspx
如果您需要更多背景信息或信息,请询问.感谢您的耐心和帮助.
我熟悉使用花括号/初始化列表来防止在初始化变量时缩小,但是在为变量赋值时使用它是一种好习惯吗?
例如
int i{1}; // initialize i to 1
double d{2.0}; // initialize d to 2.0
i = {2}; // assign value 2 to i
i = {d}; // error: narrowing from double to int
Run Code Online (Sandbox Code Playgroud)
是否有理由不使用花括号进行分配?
该表达式可在标准中的§8.5.4/ 7中的示例中找到(N3797)
unsigned int ui1 = {-1}; // error: narrows
Run Code Online (Sandbox Code Playgroud)
鉴于§8.5.4/ 7及其第4个要点:
缩小转换是隐式转换:
- 从整数类型或未范围的枚举类型到不能表示原始类型的所有值的整数类型,除非源是一个常量表达式,其整数提升后的值将适合目标类型.
我想说这里没有缩小,因为-1是一个常量表达式,其积分提升后的值适合无符号整数.
另见关于积分促销的 §4.5/ 1 :
如果int可以表示源类型的所有值,则除了bool,char16_t,char32_t或wchar_t之外的整数类型的prvalue(其整数转换等级(4.13)小于int的等级)可以转换为int类型的prvalue ; 否则,源prvalue可以转换为unsigned int类型的prvalue.
从4.13开始,我们得到-1(一个int)的等级等于unsigned int的等级,因此它可以转换为unsigned int.
编辑
不幸的是,Jerry Coffin从这个帖子中删除了他的答案.我相信他是在正确的轨道上,如果我们接受这一事实,即在标准的这一变化之后,§8.5.4/ 7中第4个要点的当前读数是错误的.
自从用g ++打开C++ 0x标准后,我开始看到'缩小转换'错误,特别是在从'int'转换为'short'时,尽管我理解错误涵盖了更广泛的转换.
任何人都可以对引入这种额外安全级别的理性有所了解吗?禁用此错误会产生什么后果?(除了潜在的精度损失).
谢谢.
在Java <8中,返回"unsafe"对象(对象或null),我能够在子类中专门化返回类型:
class A {}
class B extends A {}
interface Sup { A a(); /* returns A instance, or null */ }
interface Sub extends Sup { B a(); }
Run Code Online (Sandbox Code Playgroud)
在Java 8中,如果我想让我的API"更安全",我应该返回Optional<A>而不是"raw" A:
interface Sup { Optional<A> a(); }
interface Sub extends Sup { Optional<B> a(); }
Run Code Online (Sandbox Code Playgroud)
但是不编译!因为Optional<B>不是子类Optional<A>.
我该如何解决这个问题?