在C++ 11中,值参数(和其他值)在返回时享受隐式移动:
A func(A a) {
return a; // uses A::A(A&&) if it exists
}
Run Code Online (Sandbox Code Playgroud)
至少在MSVC 2010中,右值参考参数需要std::move:
A func(A && a) {
return a; // uses A::A(A const&) even if A::A(A&&) exists
}
Run Code Online (Sandbox Code Playgroud)
我认为内部函数,右值引用和值的行为类似,唯一的区别是在值的情况下,函数本身负责销毁,而对于右值引用,责任在外面.
在标准中对待它们的动机是什么?
Stephan T Lavavej最初的提案make_unique是N3588
它包括以下功能:
make_unique<T>(args...)
make_unique_default_init<T>()
make_unique<T[]>(n)
make_unique_default_init<T[]>(n)
make_unique_value_init<T[]>(n, args...)
make_unique_auto_size<T[]>(args...)
Run Code Online (Sandbox Code Playgroud)
然而,最终的道具,N3656,只包括make_unique(两种形式).我无法找到关于该功能的其他形式的任何讨论.我读了布里斯托尔会议的会议记录,但他们甚至没有参考原始提案.
为什么这些额外的功能不包括在最终草案中?
我之前根据参数是否constexpr询问函数重载.我正试图解决这个问题的令人失望的答案,以建立一个更聪明的断言功能.这大致是我想做的事情:
inline void smart_assert (bool condition) {
if (is_constexpr (condition))
static_assert (condition, "Error!!!");
else
assert (condition);
}
Run Code Online (Sandbox Code Playgroud)
基本上,我们的想法是编译时检查总是比运行时检查更好,如果可以在编译时检查.但是,由于内联和常量折叠之类的东西,我不能总是知道是否可以进行编译时间检查.这意味着可能存在assert (condition)编译的情况,assert(false)代码只是等待我运行它并在我发现错误之前执行该路径.
因此,如果有某种方法来检查条件是否是constexpr(由于内联或其他优化),我可以static_assert在可能的情况下调用,否则返回运行时断言.幸运的是,gcc具有内在函数__builtin_constant_p (exp),如果exp是constexpr 则返回true .我不知道其他编译器是否有这种内在的,但我希望这可以解决我的问题.这是我提出的代码:
#include <cassert>
#undef IS_CONSTEXPR
#if defined __GNUC__
#define IS_CONSTEXPR(exp) __builtin_constant_p (exp)
#else
#define IS_CONSTEXPR(exp) false
#endif
// TODO: Add other compilers
inline void smart_assert (bool const condition) {
static_assert (!IS_CONSTEXPR(condition) or condition, "Error!!!");
if (!IS_CONSTEXPR(condition))
assert (condition);
}
#undef IS_CONSTEXPR
Run Code Online (Sandbox Code Playgroud)
该static_assert …
的最新草稿结构化绑定提案(在其上的C++ 17特征是基于)的要求std::tuple_size,构件get或std::get,和std::tuple_element.以前的草稿只需要std::tuple_size和成员get或std::get.据我所知,没有讨论增加这一点,它只是出现在最终草案中.是否有令人信服的理由要求tuple_element专业化,考虑到我认为它可以作为一般实施
template<std::size_t index, typename T>
struct tuple_element {
using type = decltype(std::get<index>(std::declval<T>()));
};
Run Code Online (Sandbox Code Playgroud)
有谁知道为什么要添加此要求?
如何专门化一个采用通用参考参数的函数模板?
foo.hpp:
template<typename T>
void foo(T && t) // universal reference parameter
Run Code Online (Sandbox Code Playgroud)
Foo.cpp中
template<>
void foo<Class>(Class && class) {
// do something complicated
}
Run Code Online (Sandbox Code Playgroud)
在这里,Class不再是推断类型,因此是Class完全; 它不可能是Class &,所以参考折叠规则对我没有帮助.我或许可以创建另一个带Class &参数的特化(我不确定),但这意味着foo为所有参数的rvalue/lvalue引用的每个可能组合复制所包含的所有代码,这是通用引用应该避免的.
有没有办法实现这个目标?
如果有更好的解决方法,请更具体地说明我的问题:
我有一个可以连接到多个游戏服务器的程序,并且每个服务器在大多数情况下都使用相同的名称调用所有内容.但是,对于一些事情,它们的版本略有不同.这些东西可以有几个不同的类别:移动,项目等.我写了一个通用的"移动字符串移动枚举"内部代码调用的函数集,我的服务器接口代码有类似的功能.但是,有些服务器有自己的内部ID,它们与之通信,有些使用字符串,有些则在不同情况下使用.
现在我想做的是让它更通用一点.
我希望能够打电话ServerNamespace::server_cast<Destination>(source).这将允许我从a转换Move为a std::string或ServerMoveID.在内部,我可能需要制作副本(或从中移动),因为某些服务器要求我保留已发送消息的历史记录.通用引用似乎是解决这个问题的明显方法.
我现在想到的头文件只会暴露出来:
namespace ServerNamespace {
template<typename Destination, typename Source>
Destination server_cast(Source && source);
}
Run Code Online (Sandbox Code Playgroud)
并且实现文件将所有合法转换定义为模板特化.
c++ templates template-specialization c++11 universal-reference
std::less<T *> 无论两个指针是否指向同一个数组,都保证提供总顺序.
在标准的最新草案中,对于透明函数object std::less<void>(std::less<>)调用它时是否也是如此operator()?
显然,同样的问题适用于std::greater,但我认为它们的具体情况相同.
是否可以专门std::optional针对用户定义的类型?如果没有,那么提出这个标准是否为时已晚?
我的用例是一个类似整数的类,表示一个范围内的值.例如,你可以有一个位于[0,10]范围内的整数.我的许多应用程序甚至对单个字节的开销都很敏感,因此我将无法使用非专用std::optional的应用程序bool.但是,对于std::optional范围小于其基础类型的整数,特殊化将是微不足道的.我们可以简单地将值存储11在我的示例中.这应该不会在非可选值上提供空间或时间开销.
我可以创建这个专业namespace std吗?
我专注std::common_type于我的类型.我定义了以下专业:
common_type<my_type, my_type>
Run Code Online (Sandbox Code Playgroud)
一切都很好.然后有人来了并打电话std::common_type<my_type, my_type &>.如果传递引用而不是引用(因为它调用std::decay类型),则默认版本的行为相同.但是,它并不遵循std::common_type我需要正确工作的非参考版本.有没有比这样做更好的方法(为了简单起见,省略了对const的rvalue-reference):
common_type<my_type, my_type>
common_type<my_type, my_type &>
common_type<my_type, my_type const &>
common_type<my_type, my_type volatile &>
common_type<my_type, my_type const volatile &>
common_type<my_type, my_type &&>
common_type<my_type, my_type volatile &&>
common_type<my_type &, my_type>
common_type<my_type const &, my_type>
common_type<my_type volatile &, my_type>
common_type<my_type const volatile &, my_type>
common_type<my_type &&, my_type>
common_type<my_type volatile &&, my_type>
common_type<my_type &, my_type &>
common_type<my_type &, my_type const &>
common_type<my_type &, my_type volatile &>
...
Run Code Online (Sandbox Code Playgroud)
当然有更好的方法吗?根据我的统计,如果我们忽略const && …
c++ templates template-specialization template-meta-programming c++11
该代码有效吗?
template<bool b>
struct s {
void f() const {
}
static void f() requires b {
}
};
void g() {
s<true>().f();
}
Run Code Online (Sandbox Code Playgroud)
clang 说是,但 gcc 说不
<source>: In function 'void g()':
<source>:10:20: error: call of overloaded 'f()' is ambiguous
10 | s<true>().f();
| ~~~~~~~~~~~^~
<source>:3:14: note: candidate: 'void s<b>::f() const [with bool b = true]'
3 | void f() const {
| ^
<source>:5:21: note: candidate: 'static void s<b>::f() requires b [with bool b = true]'
5 | …Run Code Online (Sandbox Code Playgroud) #include <initializer_list>
#include <iostream>
namespace {
class C {
public:
C(C const &) = delete;
C(C &&) = delete;
C(int) {
std::cout << "int\n";
}
C(std::initializer_list<int>) {
std::cout << "initializer\n";
}
};
void f(C) {
}
// Compiles and prints "initializer" when called
C g() { return {0}; }
// Fails to compile
// C h() { return 0; }
} // namespace
int main() {
// Compiles and prints "initializer"
f({0});
// Fails to compile
// f(0);
}
Run Code Online (Sandbox Code Playgroud)
是否可以在不调用initializer_list构造函数的情况下将C(不可复制的,不可移动的类型)构造为函数参数或函数返回值?