如果你不使用异常,那么当出现错误时会发生什么?你刚才让程序崩溃了吗?
template< class T >
constexpr T&& forward( typename std::remove_reference<T>::type& t ) noexcept;
template< class T >
constexpr T&& forward( typename std::remove_reference<T>::type&& t ) noexcept;
Run Code Online (Sandbox Code Playgroud)
这两个函数返回T&&
,这(纠正我,如果我错了)折叠到
T&
if T
是左值引用T&&
if T
是rvalue引用,或者T
不是引用对于T
可能作为参考的任意类型,参考折叠总是导致forward<T>
做同样的事情forward<T&&>
吗?
如果是这样,有什么理由可以使用forward<T&&>
吗?
使用SFINAE,has_value_int<T>
并且has_value_auto<T>
都试图检测类是否T
有一个static constexpr
命名的功能value
.
int
以参数化true_type
,has_value_int<T>
适用于演示类pass
和fail
.auto
参数化true_type
,has_value_auto<T>
始终返回false.使用int
和使用之间有什么区别auto
,为什么不起作用auto
?
具体来说,为什么重载喜欢match_auto(...)
来match_auto(int)
?
#include <iostream>
using namespace std;
// parametrize true_type
template <int> using true_int = true_type; // works
template <auto> using true_auto = true_type; // does not work
// detect if T::value() is a valid compile-time expression
template <class T> …
Run Code Online (Sandbox Code Playgroud) 考虑这个例子:
#include <utility>
// runtime dominated by argument passing
template <class T>
void foo(T t) {}
int main() {
int i(0);
foo<int>(i); // fast -- int is scalar type
foo<int&>(i); // slow -- lvalue reference overhead
foo<int&&>(std::move(i)); // ???
}
Run Code Online (Sandbox Code Playgroud)
是foo<int&&>(i)
快foo<int>(i)
,还是涉及指针开销foo<int&>(i)
?
编辑:作为建议,跑步g++ -S
给了我同样51管路组件文件foo<int>(i)
和foo<int&>(i)
,但foo<int&&>(std::move(i))
导致71行的汇编代码(它看起来像差异的来源std::move
).
编辑:感谢那些推荐g++ -S
不同优化级别的人 - 使用-O3
(和制作foo noinline
)我能够获得看起来像xaxxon解决方案的输出.
在后C 预处理器递归宏中使用 Paul Fultz II 的解决方案,我想扩展无限数量的括号宏参数,例如
#define MY_CHAIN (alpha) (beta) (gamma)
Run Code Online (Sandbox Code Playgroud)
到一个逗号分隔的列表中,该列表可以传递给可变参数宏,例如
CHAIN_COMMA(MY_CHAIN) // alpha, beta, gamma
Run Code Online (Sandbox Code Playgroud)
在下面的示例中[alpha] [beta] [gamma]
,我可以扩展为大括号并使用我尝试过的所有内容分隔列表,但逗号除外alpha :: beta :: gamma
。
这是我的完整(编译)代码:
#include <iostream>
using namespace std;
// unrelated macro utilities
#define SEE(expression) cout << #expression ": " << STR(expression) << endl;
#define CMD(function, ...) function(__VA_ARGS__)
#define STR(s) CMD(STR_, s)
#define STR_(s) #s
// concatenation
#define CAT(x, y) CAT_(x, y)
#define CAT_(x,y) x ## y // error from CHAIN_COMMA: passed 4 …
Run Code Online (Sandbox Code Playgroud) 在下面的示例代码中,我想知道两次调用log_cref_address
何时可靠地打印相同的地址.
#include <iostream>
#include <thread>
#include <functional>
using namespace std;
void log_cref_address(const int& t) {
cout << addressof(t) << ' ';
}
template <int i>
void foo() {
log_cref_address(i); // different if foo called from different threads
thread([] { log_cref_address(i); }).join(); // same if already in thread
thread(log_cref_address, i).join(); // same if already in thread
cout << endl;
}
int main() {
// first three calls print identical addresses
cout << "foo<0>: "; foo<0>();
cout << "foo<0>: "; …
Run Code Online (Sandbox Code Playgroud) c++ cross-platform addressof stack-memory pass-by-const-reference