小编Dav*_*one的帖子

为什么C++ 11具有值参数的隐式移动,而不是rvalue参数?

在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)

我认为内部函数,右值引用和值的行为类似,唯一的区别是在值的情况下,函数本身负责销毁,而对于右值引用,责任在外面.

在标准中对待它们的动机是什么?

c++ rvalue-reference move-semantics c++11 c++20

21
推荐指数
3
解决办法
3688
查看次数

make_unique数组,原始提案与final

Stephan T Lavavej最初的提案make_uniqueN3588

它包括以下功能:

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(两种形式).我无法找到关于该功能的其他形式的任何讨论.我读了布里斯托尔会议的会议记录,但他们甚至没有参考原始提案.

为什么这些额外的功能不包括在最终草案中?

c++ standard-library c++14

15
推荐指数
1
解决办法
1073
查看次数

constexpr,static_assert和inlining

我之前根据参数是否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++ inline static-assert constexpr c++11

13
推荐指数
2
解决办法
4713
查看次数

为什么结构化绑定依赖于tuple_element?

最新草稿结构化绑定提案(在其上的C++ 17特征是基于)的要求std::tuple_size,构件getstd::get,和std::tuple_element.以前的草稿只需要std::tuple_size和成员getstd::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)

有谁知道为什么要添加此要求?

c++ c++17 structured-bindings

13
推荐指数
1
解决办法
388
查看次数

专门化一个带有通用引用参数的函数模板

如何专门化一个采用通用参考参数的函数模板?

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::stringServerMoveID.在内部,我可能需要制作副本(或从中移动),因为某些服务器要求我保留已发送消息的历史记录.通用引用似乎是解决这个问题的明显方法.

我现在想到的头文件只会暴露出来:

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

10
推荐指数
1
解决办法
918
查看次数

std :: less <void>和指针类型

std::less<T *> 无论两个指针是否指向同一个数组,都保证提供总顺序.

在标准的最新草案中,对于透明函数object std::less<void>(std::less<>)调用它时是否也是如此operator()

显然,同样的问题适用于std::greater,但我认为它们的具体情况相同.

c++ language-lawyer c++14

10
推荐指数
1
解决办法
856
查看次数

专攻std :: optional

是否可以专门std::optional针对用户定义的类型?如果没有,那么提出这个标准是否为时已晚?

我的用例是一个类似整数的类,表示一个范围内的值.例如,你可以有一个位于[0,10]范围内的整数.我的许多应用程序甚至对单个字节的开销都很敏感,因此我将无法使用非专用std::optional的应用程序bool.但是,对于std::optional范围小于其基础类型的整数,特殊化将是微不足道的.我们可以简单地将值存储11在我的示例中.这应该不会在非可选值上提供空间或时间开销.

我可以创建这个专业namespace std吗?

c++ std template-specialization c++14

9
推荐指数
2
解决办法
848
查看次数

接受所有版本的const/volatile资格和&vs &&的类模板特化

我专注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

9
推荐指数
1
解决办法
725
查看次数

带约束重载静态和非静态成员函数

该代码有效吗?

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)

c++ language-lawyer c++-concepts c++20

9
推荐指数
1
解决办法
247
查看次数

在不调用initializer_list构造函数的情况下,将不可复制的不可移动类型构造为函数参数

#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(不可复制的,不可移动的类型)构造为函数参数或函数返回值?

c++ initializer-list c++11

8
推荐指数
1
解决办法
497
查看次数