- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
已知std::array::operator[]
由于 C++14 是 constexpr
,请参见下面的声明:
constexpr const_reference operator[]( size_type pos ) const;
但是,它也是 const
限定的。如果您想使用 std::array
的下标运算符以便在编译时为数组赋值,这会产生影响。例如考虑以下用户文字:
template<typename T, int N>
struct FooLiteral {
std::array<T, N> arr;
constexpr FooLiteral() : arr {} { for(int i(0); i < N; ++i) arr[i] = T{42 + i}; }
};
如果您尝试声明类型为 FooLiteral
的 constexpr
变量,上述代码将无法编译。这是因为重载解析规则将数组下标运算符的非 const 限定、非 constexpr 重载限定为更好的匹配。因此,编译器会提示调用非 constexpr
函数。
我无法弄清楚委员会将此重载声明为符合 C++14 条件的 const
的原因是什么,但是似乎人们注意到了其中的含义,并且还有一个提案p0107R0在即将发布的 C++17 中修复此问题。
对于 C++14,我很自然地要克服这个问题,以某种方式破解表达式,以唤起正确的下标运算符。我所做的是:
template<typename T, int N>
struct FooLiteral {
std::array<T, N> arr;
constexpr FooLiteral() : arr {} {
for(int i(0); i < N; ++i) {
const_cast<T&>(static_cast<const std::array<T, N>&>(arr)[i]) = T{42 + i};
}
}
};
那是我将数组转换为 const
引用以引发正确的下标运算符重载,然后我将 const_cast
重载下标运算符的返回对象转换为 T&
为了移除它的 const-ness 并能够分配给它。
这很好用,但我知道 const_cast
应该谨慎使用,坦率地说,我对这个 hack 是否会导致未定义的行为有重新考虑。
直觉上,我不认为有问题,因为这个 const_cast
发生在编译时初始化,因此我想不出在这种状态下可能出现的含义。
但是是这样吗,还是我错了,这将 UB 引入了程序?
有人可以证明这是否是 UB 吗?
最佳答案
据我所知,这不是未定义的行为。提案that added constexpr operator[]
发生在 changes that removed the implicit const from constexpr member functions 之前.所以看起来他们只是在 constexpr 上添加,而没有考虑是否需要保留 const。
我们可以看到 Relaxing constraints on constexpr functions 的早期版本它说了以下关于在常量表达式中改变文字的内容:
Objects created within a constant expression can be modified within the evalution of that constant expression (including the evaluation of any constexpr function calls it makes), until the evaluation of that constant expression ends, or the lifetime of the object ends, whichever happens sooner. They cannot be modified by later constant expression evaluations. [...]
This approach allows arbitrary variable mutations within an evaluation, while still preserving the essential property that constant expression evaluation is independent of the mutable global state of the program. Thus a constant expression evaluates to the same value no matter when it is evaluated, excepting when the value is unspecified (for instance, floating-point calculations can give different results and, with these changes, differing orders of evaluation can also give different results).
我们可以看到我引用的早期提案指出了 const_cast
hack 并且它说:
In C++11, constexpr member functions are implicitly const. This creates problems for literal class types which desire to be usable both within constant expressions and outside them:
[...]
Several alternatives have been suggested to resolve this problem:
- Accept the status quo, and require users to work around this minor embarrassment with const_cast.
关于c++ - 在编译时填充 std::array 和 const_cast 可能的未定义行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34338241/
我正在阅读 C++ Primer,我发现了一些非常奇怪且难以理解的东西: Record lookup(Account&); //Record and Account are two unrelate
我的问题是,为什么代码的第一部分不起作用而第二部分有效。非常量指针应该修改之前使用 const_cast 的 const 值,但是对于整数这个技巧不起作用。您能解释一下为什么会这样吗? const i
我已经阅读了很多关于 C++ 中的 const_cast 被认为是错误和危险的讨论,除了向后兼容 C 代码之外,不应将其用于任何其他用途。我大体上同意。 但是最近我遇到了以下用例,这让我感到好奇。 我
C++ Primer 一书的第 6.4 章陈述如下: In § 4.11.3 (p. 163) we noted that const_casts are more useful in the con
我看到这个 post这解释了const_cast<>并说使用指针/引用是有益的。但是,请考虑以下代码: 1- const_cast(xadj) 我得到 invalid const_cast from
我正在阅读有关 c++ 中的 const_cast 运算符 1.我无法理解的第一件奇怪的事情是 const_cast 运算符语法即 -const_cast----(--expression--)---
这个问题在这里已经有了答案: const_cast doesn't work c++? [duplicate] (3 个答案) 关闭 6 年前。 在const_cast之后,main函数中的值没有变
这个问题在这里已经有了答案: Two different values at the same memory address (7 个答案) 关闭 5 年前。 我有以下代码: int main(){
这个问题在这里已经有了答案: Two different values at the same memory address (7 个答案) 关闭 5 年前。 #include using nam
我想使用 C++ 格式进行此转换,它以 C 方式工作。但是当我尝试使用 C++ 格式时它失败了。 有效! void req_password(const void *data, size_t data
我有一个管理输入的类。要显示和更改键绑定(bind),重要的是在完成后将其提交给管理器之前,为调用者提供它可以拥有和更改的绑定(bind)的映射。但是,这个映射中可以插入/删除什么的具体规则只有管理者
我对 const_cast 的返回类型有点困惑?尖括号内的类型是否 <>是返回类型吗? const int i = 5; int b = const_cast(i); 是const_cast返回 in
我有一个函数 static bool Validate(const char& letter, string& aWord) 我需要调用它 Validate(letter, aWord); // wh
这个问题在这里已经有了答案: Two different values at the same memory address (7 个答案) 关闭 5 年前。 考虑以下代码: 我声明了一个新的引用端
我有一个大型库,它实现了一些不可变的数据结构。可以想象,其中几乎所有内容都是 const合格的。有一些选择部分不是 const,例如引用计数器。为了处理嵌入结构中的引用计数器,这些引用计数器只能通过
长话短说是否适用于: mapm; m.insert( make_pair( 1, 40 ) ); for( map::iterator it = m.begin(); it !
据我所知,在类中创建常量函数对于读/写编译器优化很有用。 类中的常量函数意味着类成员在函数执行期间将保持不变。但是,您可以通过 const 强制转换隐式参数来绕过此问题(当然,这是一种非常糟糕的做法)
这个问题在这里已经有了答案: Two different values at the same memory address (7 个答案) 关闭 5 年前。 考虑以下代码: 我声明了一个新的引用端
考虑以下 C++03 程序: #include struct T { mutable int x; T() : x(0) {} }; void bar(int& x) { x
我正在查看我即将开始使用的 API 的一些示例代码。以下模式让我有点困惑: char* str; str = const_cast("Hello World"); printf("%s ", str)
我是一名优秀的程序员,十分优秀!