(注意!这个问题特别涵盖了 C++17 中引入内联变量之前 C++14 的状态)
(...可能是 [basic.def.odr]/3;但是一旦在内联函数定义的上下文中获取这样一个 constexpr 变量的地址,这是否可以在程序中默默地引入 UB?)
TLDR 示例:执行一个程序,其doMath()定义如下:
// some_math.h
#pragma once
// Forced by some guideline abhorring literals.
constexpr int kTwo{2};
inline int doMath(int arg) { return std::max(arg, kTwo); }
// std::max(const int&, const int&)
Run Code Online (Sandbox Code Playgroud)
一旦doMath()在两个不同的翻译单元中定义(例如通过包含some_math.h并随后使用doMath()),就会有未定义的行为吗?
考虑以下示例:
// constants.h
#pragma once
constexpr int kFoo{42};
// foo.h
#pragma once
#include "constants.h"
inline int foo(int arg) { return arg * kFoo; …Run Code Online (Sandbox Code Playgroud) 我试图解决以下问题:http: //www.spoj.pl/problems/TRIP/
我在C++中使用DP(动态编程)编写了一个解决方案(下面发布的代码).但我得到了TLE(时间限制超过).如何优化我的代码?
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
string a,b;
vector<string> v;
int dp[85][85];
void filldp()
{
for(int i = 0; i <= a.length(); i++)
dp[i][0] = 0;
for(int i = 0; i <= b.length(); i++)
dp[0][i] = 0;
for(int i = 1; i <= a.length(); i++)
for(int j = 1; j<= b.length(); j++)
if(a[i-1] == b[j-1])
dp[i][j] = dp[i-1][j-1] + 1;
else
dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
}
vector<string> fillv(int i, int j) …Run Code Online (Sandbox Code Playgroud) NSNumber引用类型,例如Int32,UInt32,Int64和UInt64类型?具体来说,复制下面介绍的自动按配置桥接.此类解决方案的示例用法:
let foo : Int64 = 42
let bar : NSNumber = foo
/* Currently, as expected, error:
cannot convert value of type 'Int64' to specified type 'NSNumber */
Run Code Online (Sandbox Code Playgroud)
一些原生的Swift数(值)类型可以自动桥接到NSNumber(引用)类型:
迅数字结构类型的实例,例如
Int,UInt,Float,Double,和Bool,不能由来表示AnyObject类型,因为AnyObject仅代表一个类类型的实例.但是,Foundation启用桥接时,可以将Swift数值分配给常量和AnyObject类型的变量 作为类的桥接实例NSNumber....
雨燕自动填补某些本地号码类型,如
Int和Float,对NSNumber.此桥接允许您NSNumber从以下类型之一创建 : …
Cppreference:s部分std::unique_ptr显示了以下演示,用于为unique_ptr实例提供自定义删除器:
Run Code Online (Sandbox Code Playgroud)std::unique_ptr<D, std::function<void(D*)>> p(new D, [&](D* ptr) { std::cout << "destroying from a custom deleter...\n"; delete ptr; });
D就这个问题而言,where就是简单的自定义类型,比如说
struct D
{
D() { std::cout << "D CTOR\n"; }
~D() { std::cout << "D DTOR\n"; }
};
Run Code Online (Sandbox Code Playgroud)
此外,上面的参考资料说明了对删除器的以下类型要求:
类型要求
Deletermust beFunctionObjector lvalue reference to aFunctionObjector lvalue reference to function, callable with an argument of typeunique_ptr<T, Deleter>::pointer...
会员类型
pointer:std::remove_reference<Deleter>::type::pointer如果该类型存在,否则T*. 必须满足NullablePointer。 …
我试图了解类型特征传播背后的机制,如http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0602r4.html 中std::optional 所述。复制操作的处理有细微的差别,复制操作应有条件地定义为删除,而移动操作则不应参与重载决议。
这种差异的原因是什么,我将如何测试后者?例子:
#include <type_traits>
#include <optional>
struct NonMoveable {
NonMoveable() = default;
NonMoveable(NonMoveable const&) = default;
NonMoveable(NonMoveable&&) = delete;
NonMoveable& operator=(NonMoveable const&) = default;
NonMoveable& operator=(NonMoveable&&) = delete;
};
// Inner traits as expected
static_assert(!std::is_move_constructible<NonMoveable>::value);
static_assert(!std::is_move_assignable<NonMoveable>::value);
// The wrapper is moveable, via copy operations participating in
// overload resolution. How to verify that the move operations don't?
static_assert(std::is_move_constructible<std::optional<NonMoveable>>::value);
static_assert(std::is_move_assignable<std::optional<NonMoveable>>::value);
int main(int argc, char* argv[])
{
NonMoveable a1;
NonMoveable a2{std::move(a1)}; // Bad, as expected
std::optional<NonMoveable> b1;
std::optional<NonMoveable> …Run Code Online (Sandbox Code Playgroud) 以下所有标准参考均指N4659:2017 年 3 月后 Kona 工作草案/C++17 DIS。
考虑以下类模板A和类B,其私有定义了嵌套类C和枚举类E:
template<typename T, typename U>
class A {};
class B {
class C {};
enum class E {};
};
Run Code Online (Sandbox Code Playgroud)
通常的访问检查规则不适用于用于指定显式实例化的名称。[...]
在指定显式实例化时,我们可以参考例如模板参数列表中的B::C和等私有类型B::E:
// OK: explicit instantiation definition.
template class A<B::C, B::E>;
Run Code Online (Sandbox Code Playgroud)
我试图在标准中找到类似的部分,该部分指定在为(部分和特别显式/完全)专业化指定模板参数列表时是否同样放弃访问权限限制。
// Partial specialization.
template<typename U>
class A<B::C, U> {};
// Explicit(/full) specialization.
template<>
class A<B::C, B::E> {};
Run Code Online (Sandbox Code Playgroud)
部分专业化无法在 Clang 中编译
Run Code Online (Sandbox Code Playgroud)error: 'C' is a private …
以下代码片段格式正确吗?
struct A { ~A() = delete; };
A *pa{new A{}};
class B { ~B() = default; };
B *pb{new B{}};
Run Code Online (Sandbox Code Playgroud)
A乍一看,B似乎从未使用过的已删除 dtor和私有显式默认 dtor从未使用过(有意的内存泄漏,如果您愿意的话),这可以说是格式良好的。
Clang 接受各种编译器和 C++ 版本(C++11 到 C++2a)的程序。
另一方面,GCC 拒绝针对各种编译器和 C++ 版本的程序。
Run Code Online (Sandbox Code Playgroud)struct A { ~A() = delete; }; A *pa{new A{}}; // GCC error: use of deleted function 'A::~A()' class B { ~B() = default; }; B *pb{new B{}}; // GCC error: 'B::~B()' is private within this context
(如果格式正确;在我提交错误报告之前:是否有针对此极端情况的任何开放的 GCC 错误报告?我自己搜索了 GCC:s bugzilla 无济于事。) …
除非另有说明,否则以下所有标准参考均指N4861(2020 年 3 月布拉格后工作草案/C++20 DIS)。
背景
如果基类是可访问的,则可以将指向派生类的指针隐式转换为指向该基类的指针 [...]。
这意味着以下示例是格式良好的:
class N {};
class P : private N {
friend void f();
};
void f() {
P p{};
N* n = &p; // R: OK as per [class.access.base]/5
}
Run Code Online (Sandbox Code Playgroud)
asN是R上面(+)处的可访问基类。
[class.access.base]/5 还提到[强调我的]:
对成员的访问受命名该成员的类的影响。此命名类是在其中查找并找到成员名称的类。[注: [...]如果两个类成员访问运算符和一个合格-ID被用于命名构件(如在
p->T?::?m),类命名构件是由合格的嵌套名称说明符所表示的类-id(即,T)。—尾注 ]
和[强调我的]:
一个成员在类中命名时
m可以访问,如果RN
- [...]
- /5.3
m作为的成员N …
我一直在试图理解std::nullopt_t不允许DefaultConstructible在 C++17(引入它的地方)及更高版本中的基本原理,并在此过程中解决了一些编译器差异混淆。
考虑以下违反规范的(它是DefaultConstructible)实现nullopt_t:
struct nullopt_t {
explicit constexpr nullopt_t() = default;
};
Run Code Online (Sandbox Code Playgroud)
它是 C++11 和 C++14(无用户提供的构造函数)中的聚合,但不是 C++17(构造函数explicit)和 C++20(用户声明的构造函数)中的聚合。
现在考虑以下示例:
struct S {
constexpr S() {}
S(S const&) {}
S& operator=(S const&) { return *this; } // #1
S& operator=(nullopt_t) { return *this; } // #2
};
int main() {
S s{};
s = {}; // GCC error: ambiguous overload for 'operator=' (#1 and #2)
}
Run Code Online (Sandbox Code Playgroud)
这在 …
最近提出一个有趣的 C 语言律师问题:
此问答针对 C++ (*)的类似情况提出了相同的问题:这些是否有效?
enum EA { a } ea = EA(2); // #1
enum EB { b } eb = static_cast<EB>(2); // #2
Run Code Online (Sandbox Code Playgroud)
我已经注意到,该变体在编译时被拒绝(“无法用‘ ’类型的右值初始化‘ ’类型的enum EC { c } ec = EC{2};值),而和被接受,排除格式错误但不排除格式错误的 NDR 和 UB对于和。Eint#1#2#1#2
(*) 在被提示对最初的 C 语言律师问题给出过于热切和错误的以 C++ 为中心的答案后,在此发布为自我回答的问答。