const限定的许多好处之一是使API更容易理解,例如:
template<typename T> int function1(T const& in);
// clearly, the input won’t change through function1
Run Code Online (Sandbox Code Playgroud)
通过引入rvalue引用,可以从完美转发中受益,但通常会删除const限定符,例如:
template<typename T> int function2(T&& in);
// can explicitly forward the input if it's an rvalue
Run Code Online (Sandbox Code Playgroud)
除了文档之外,还有一种很好的方法来描述function2不会改变它的输入吗?
请考虑以下代码:
#include <iostream>
template<typename T>
void inc1(T&& x)
{
T y = x;
++y;
}
template<typename T>
void inc2(T& x)
{
T y = x;
++y;
}
int main()
{
int a = 10;
inc1(a); // a is now 11
int b = 10;
inc2(b); // b remains 10
}
Run Code Online (Sandbox Code Playgroud)
替换后我们有
void inc1(int& x)
{
int& y = x; // reference to x
++y; // increments x
}
void inc2(int& x)
{
int y = x; // copy of x …Run Code Online (Sandbox Code Playgroud) 请考虑以下代码:
void f(float x)
{
x * (true ? 1.f : 0.0);
}
Run Code Online (Sandbox Code Playgroud)
类型declval(bool) ? declval(float) : declval(double)是double根据C++标准[expr.cond].
这是否意味着上述代码必须等同于:
void f(float x)
{
double(x) * 1.0;
}
Run Code Online (Sandbox Code Playgroud)
或者是否有一个语句允许在第一个操作数?:是编译时常量表达式的情况下进行优化?
在以下代码中
#include <initializer_list>
#include <utility>
template<typename T> void f(T&& x) {}
template<typename T> void g(std::initializer_list<T> x) {}
int main()
{
auto x = {0}; // OK
auto&& y = {0}; // OK
g(x); // OK
g(std::move(x)); // OK
g({0}); // OK
f(x); // OK
f(std::move(x)); // OK
f({0}); // failure
return 0;
}
Run Code Online (Sandbox Code Playgroud)
rvalue initializer_list可以推导,auto但不能推断template.
为什么C++会禁止这个?
在下面的:
auto x = {0}; // auto deduction of std::initializer_list<int>
auto y = []() -> std::initializer_list<int> { return {0}; }(); //explicit
auto z = []() { return {0}; }(); // won't compile
Run Code Online (Sandbox Code Playgroud)
为什么不能返回并自动推断出std :: initializer_list的类型?
对于以下代码
struct X
{
int x;
X() noexcept try : x(0)
{
}
catch(...)
{
}
};
Run Code Online (Sandbox Code Playgroud)
Visual Studio 14 CTP发出警告
警告C4297:'X :: X':函数假定不抛出异常,但确实如此
注意:在函数上指定了__declspec(nothrow),throw(),noexcept(true)或noexcept
这是滥用noexcept吗?或者它是Microsoft编译器中的错误?
我对设计有一些疑问std::initializer_list.我在[support.initlist]中找不到答案.
为什么它有一个显式定义的默认构造函数?
为什么这个构造函数不是constexpr?
为什么方法size()不是constexpr?
为什么没有特质给出大小initializer_list(如专精std::tuple_size)?
为什么不可能静态访问其元素(如专业化std::get)?
sizeof适用于什么时会发生什么initializer_list?
为什么将局部变量用作非类型参数是非法的?
例如,在下一个代码local_var中不能参数X.
template<int& x> struct X {};
void f(int local_var)
{
X<local_var> x;
}
Run Code Online (Sandbox Code Playgroud) 编译器是否可以在非标准布局类中重新排序数据?例如,是否允许更改
struct
{
char x;
private:
short y;
public:
char z;
};
Run Code Online (Sandbox Code Playgroud)
至
struct
{
private:
short y;
public:
char x;
char z;
};
Run Code Online (Sandbox Code Playgroud) 以下代码看起来合法但不编译
void f() {}
template<bool>
struct call_any
{
template<typename F>
static void call(F f) {}
};
template<bool B>
void call_f()
{
call_any<true>::call<void (&)()>(f); // OK
call_any<false>::call<void (&)()>(f); // OK
call_any<B>::call<void()>(f); // OK
call_any<B>::call<void (&)()>(f); // expected primary-expression before '>'
}
Run Code Online (Sandbox Code Playgroud)
为什么会出现错误,这是什么意思?