Tag: language lawyer

为什么gcc和clang都会为这个程序产生不同的输出? (转换运算符vs构造函数)

程序: #include <stdio.h> struct bar_t { int value; template<typename T> bar_t (const T& t) : value { t } {} // edit: You can uncomment these if your compiler supports // guaranteed copy elision (c++17). Either way, it // doesn't affect the output. // bar_t () = delete; // bar_t (bar_t&&) = delete; // bar_t […]

函数参数的破坏顺序是什么?

如果分别用参数a_1 ,…, a_n调用types为T_1 ,…, T_n参数为p_1 ,…, p_n的函数f ,并且它的主体抛出一个exception,按照什么顺序完成或返回争论被毁,为什么? 如果可能,请提供标准参考。 编辑:我其实想问一下关于函数的“参数”,但是当TC和Columbo设法解决了我的困惑时,我将这个问题留给了参数,并且询问了一个关于参数的新的单独问题 。 请参阅关于这个问题的评论。

将函数模板中的静态局部variables的地址用作types标识符是否安全?

我希望创build一个替代std::type_index不需要RTTI : template <typename T> int* type_id() { static int x; return &x; } 请注意,局部variablesx的地址被用作typesID,而不是x本身的值。 另外,我不打算在现实中使用裸指针。 我刚刚清除了与我的问题无关的所有内容。 看到我的实际type_index实施在这里 。 这种方法是否合理?如果是这样,为什么? 如果没有,为什么不呢? 我觉得我在这里摇摇欲坠,所以我对我的方法为什么会起作用或不起作用的确切原因感兴趣。 一个典型的用例可能是在运行时注册例程以通过单个接口处理不同types的对象: class processor { public: template <typename T, typename Handler> void register_handler(Handler handler) { handlers[type_id<T>()] = [handler](void const* v) { handler(*static_cast<T const*>(v)); }; } template <typename T> void process(T const& t) { auto […]

为什么在lambdas中隐式捕获const int(或shorts)?

这编译: int main() { const int x = 123; auto g = []() { std::cout << x << "\n"; }; g(); } 但是这个: int main(){ const float x = 123; auto g = []() { std::cout << x << "\n"; }; g(); } 生产: “错误:'x'未被捕获” 为什么? 我已经在GCC(从5.0.0到8.0.0的各种版本)和Clang(从4.0.0到6.0.0的各种版本)上testing过它。 它在所有情况下performance相同。

在头文件中使用lambda是否违反了ODR?

以下内容可以写在一个头文件中: inline void f () { std::function<void ()> func = [] {}; } 要么 class C { std::function<void ()> func = [] {}; C () {} }; 我猜在每个源文件中,lambda的types可能是不同的,因此在std::function ( target_type的结果将不同)中包含的types。 这是否违反ODR( 一个定义规则 ),尽pipe看起来像一个共同的模式和合理的事情? 第二个示例是否每次都违反了ODR,或者只有至less一个构造函数在头文件中?

传递一个C ++对象到自己的构造函数合法吗?

我惊讶地意外地发现以下的作品: #include <iostream> int main(int argc, char** argv) { struct Foo { Foo(Foo& bar) { std::cout << &bar << std::endl; } }; Foo foo(foo); // I can't believe this works… std::cout << &foo << std::endl; // but it does… } 我将构造对象的地址传递给它自己的构造函数。 这看起来像来源层面的循环定义。 标准是否真的允许你在对象构造之前将一个对象传入一个函数,或者这个未定义的行为? 我想这并不奇怪,因为所有的类成员函数都有一个指向其类实例的数据的指针,作为一个隐式参数。 数据成员的布局在编译时是固定的。 请注意,我不是问这是否有用或好主意, 我只是在学习更多的课程。

C ++标准是否在C ++ 14中使用了不确定的值和未定义的行为?

如在初始化中涉及左值到右值的转换? 是int x = x; UB? C ++标准在第3.3.2节的声明中有一个令人惊讶的例子,其中一个int用它自己的不确定值进行初始化: int x = 12; { int x = x; } 这里第二个x是用自己的(不确定的)值初始化的。 – 结束示例 ] 哪个Johannes回答这个问题表明是未定义的行为,因为它需要一个左值到右值的转换。 在最新的C ++ 14草案标准N3936可以在这里find这个例子已经改为: unsigned char x = 12; { unsigned char x = x; } 这里第二个x是用自己的(不确定的)值初始化的。 – 结束示例 ] 在C ++ 14中,在不确定的值和未定义的行为方面有什么改变,导致了这个例子的改变?