取以下合法代码:
bool bar();
template <class T>
constexpr bool foo(T t) {
if (t>0) {
return true;
}
return bar();
}
int main() {
//constexpr bool cb1 = foo(-1); // error as expected because it would attempt to call bar()
constexpr bool cb2 = foo(1); // ok
}
Run Code Online (Sandbox Code Playgroud)
因此,只要我们没有在编译时评估上下文中遇到非 constexpr 代码路径,我们的 constexpr 就形成了良好的格式。整洁的!
但是,如果我应用相同的实际概念,但碰巧在条件代码路径中包含非文字类型,例如std::string,则标准说不:
#include <string>
bool bar(std::string);
template <class T>
constexpr bool foo(T t) {
if (t>0) {
return true;
}
std::string s = "abc";
return bar(s); …Run Code Online (Sandbox Code Playgroud) 我正在观看Alexandrescu的视频,他有以下代码片段:
// an example implementation of a single threaded shared_ptr
~SingleThreadPtr() {
if(!c_) {
soSueMe: delete p_;
} else if(--*c_ == 0) {
delete c_;
goto soSueMe;
}
}
Run Code Online (Sandbox Code Playgroud)
这是https://youtu.be/Qq_WaiwzOtI?t=36m44s.他说,"我使用我着名的'goto soSueMe'构造",并说"试着写下这个没有goto和[..]你会发现它很难".
这里有什么困难?是不是以下相同,显然不难,更可读:
// an example implementation of a single threaded shared_ptr
~SingleThreadPtr() {
if(!c_) {
delete p_;
} else if(--*c_ == 0) {
delete c_;
delete p_;
}
}
Run Code Online (Sandbox Code Playgroud)
或者是不是一样的(从而加强了反对的论点goto)?什么样的黑客黑魔法伏都教在这里?
此问题假设您熟悉P1895R0 中tag_invoke引入的定制点管理技术。
自定义点对象可以根据 P1895R0 定义为:
inline constexpr struct foo_cpo {
// simplified original by omitting noexcept forward and using auto arg
auto operator()(auto const &x) -> decltype( std::tag_invoke(*this, x) ) {
return std::tag_invoke(*this, x); // <--^-- here are the Niebloid
}
} foo;
Run Code Online (Sandbox Code Playgroud)
但是鉴于这种技术的关键是直接处理对象,并将任何和所有 ADL 委托给一个且唯一商定的 identifier tag_invoke,那么似乎可以通过简单的方式实现相同的效果,
inline constexpr struct {
auto operator()(auto const &x) -> decltype( tag_invoke(*this, x) ) {
return tag_invoke(*this, x); // no Niebloid. directly ADL call tag_invoke
}
} …Run Code Online (Sandbox Code Playgroud) 问题在下面的代码中,询问使用的值初始化语法是否意味着对于各个位字段成员是零初始化还是未初始化:
struct S { // S is POD
int a : 3;
int b : 1;
};
S s1;
S s2{};
s1.a; // uninitialized (ok, we understand this)
s1.b; // "
s2.a; // zero or junk?
s2.b; // "
Run Code Online (Sandbox Code Playgroud)
以下是位域的复习:https://en.cppreference.com/w/cpp/language/bit_field
为具有许多位字段的结构创建归零构造函数通常使用遗留代码中的丑陋memset来完成,因为在构造函数初始化列表中使用value-init语法重复每个位域成员的名称会产生无法管理的代码.即使结构是用于良好测量的POD,也可以完成此操作.想要在C++ 11中尽可能消除这种情况(不幸的是,默认成员初始化语法不适用于位字段,直到C++ 20).C++ 11是否使用{} -init语法保证对此进行零初始化?
// file1.cpp
struct Foo {
virtual void boo() final;
};
// file2.cpp
struct Foo {
virtual void boo();
};
Run Code Online (Sandbox Code Playgroud)
这是ODR还是其他一些语言规则违规?
这是一些代码:
template<class T>
inline void bar(T& t) {
foo(t); // intention is that foo() is found by ADL
}
struct Wig {
int i;
};
void foo(int){ }
// some convenience overload
inline void bar(const Wig& w) { foo(w.i); }
// The bit that if uncommented, "fixes" the problem
//inline void bar(Wig& w) { foo(w.i); }
int main()
{
Wig w;
bar(w);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Clang 3.5和Gcc 4.7,吐出以下错误:
template-function-overload.cpp:12:4: error: no matching function for call to 'foo'
foo(t);
^~~
template-function-overload.cpp:29:4: …Run Code Online (Sandbox Code Playgroud)