小编mar*_*n78的帖子

C++函数类型

我在理解函数类型时遇到问题(它们看起来像是a的Signature模板参数std::function):

typedef int Signature(int); // the signature in question

typedef std::function<int(int)>  std_fun_1;
typedef std::function<Signature> std_fun_2;

static_assert(std::is_same<std_fun_1, std_fun_2>::value,
              "They are the same, cool.");

int square(int x) { return x*x; }

Signature* pf = square;   // pf is a function pointer, easy
Signature f;              // but what the hell is this?
f(42);                    // this compiles but doesn't link
Run Code Online (Sandbox Code Playgroud)

变量f无法分配,但可以调用.奇怪的.那有什么好处呢?

现在,如果我对typedef进行const限定,我仍然可以使用它来构建更多类型,但显然没有别的:

typedef int ConstSig(int) const;

typedef std::function<int(int) const>  std_fun_3;
typedef std::function<ConstSig>        std_fun_4;

static_assert(std::is_same<std_fun_3, std_fun_4>::value,
              "Also the same, …
Run Code Online (Sandbox Code Playgroud)

c++ function-pointers c++11 std-function

18
推荐指数
1
解决办法
2万
查看次数

使用unordered_map的模板代码膨胀

我想知道是否unordered_map使用类型擦除实现,因为unordered_map<Key, A*>并且unordered_map<Key, B*>可以使用完全相同的代码(除了强制转换,这是机器代码中的无操作).也就是说,两者的实现可以基于unordered_map<Key, void*>保存代码大小.

更新:此技术通常被称为精简模板成语(感谢下面的评论者指出这一点).

更新2:我对Howard Hinnant的观点特别感兴趣.我希望他读到这个.

所以我写了这个小测试:

#include <iostream>

#if BOOST
# include <boost/unordered_map.hpp>
  using boost::unordered_map;
#else
# include <unordered_map>
  using std::unordered_map;
#endif

struct A { A(int x) : x(x) {} int x; };
struct B { B(int x) : x(x) {} int x; };

int main()
{
#if SMALL
    unordered_map<std::string, void*> ma, mb;
#else
    unordered_map<std::string, A*> ma;
    unordered_map<std::string, B*> mb;
#endif

    ma["foo"] = new …
Run Code Online (Sandbox Code Playgroud)

c++ boost unordered-map type-erasure libc++

17
推荐指数
1
解决办法
796
查看次数

如何欺骗boost :: asio以允许只移动处理程序

在RPC通信协议中,在调用方法之后,我将"完成"消息发送回调用者.由于以并发方式调用方法,因此包含响应(a std::string)的缓冲区需要由互斥锁保护.我想要实现的目标如下:

void connection::send_response()
{
    // block until previous response is sent
    std::unique_lock<std::mutex> locker(response_mutex_);

    // prepare response
    response_ = "foo";

    // send response back to caller. move the unique_lock into the binder
    // to keep the mutex locked until asio is done sending.
    asio::async_write(stream_,
                      asio::const_buffers_1(response_.data(), response_.size()),
                      std::bind(&connection::response_sent, shared_from_this(),
                                _1, _2, std::move(locker))
                      );
}

void connection::response_sent(const boost::system::error_code& err, std::size_t len)
{
    if (err) handle_error(err);
    // the mutex is unlocked when the binder is destroyed
}
Run Code Online (Sandbox Code Playgroud)

但是,这无法编译,因为boost::asio需要处理程序是CopyConstructible. …

c++ boost boost-asio move-semantics c++11

17
推荐指数
1
解决办法
1929
查看次数

表达式包含未展开的参数包

不知怎的,我不知道如何扩展可变参数模板参数包.以下代码有什么问题?

#include <iostream>

template <typename T>
struct print_one
{
    static void run(const T& t)
    {
        std::cout << t << ' ';
    }
};

template<typename... Args>
void print_all(Args&&... args)
{
    // the next line doesn't compile:
    print_one<Args>::run(std::forward<Args>(args))...;
}

int main()
{
    print_all(1.23, "foo");
}
Run Code Online (Sandbox Code Playgroud)

Clang说,Expression contains unexpanded parameter packs 'Args' and 'args'.为什么?

c++ templates variadic-templates c++11

14
推荐指数
2
解决办法
1万
查看次数

快速移动任务与Howard Hinnant的short_alloc

我正在使用Howard Hinnant很好的基于竞技场的小分配器,short_alloc.

让我感到震惊的是,从一个已经超出其竞技场并因此在堆上分配的向量进行移动分配可以使用通常的快速移动分配(即,抓取目标的资源)来完成.然而,这种情况并非如此:

typedef arena<16>                     arena_type;
typedef short_alloc<int, 16>          alloc_type;
typedef std::vector<int, alloc_type>  vec_type;

arena_type arena1, arena2;
vec_type vec1(alloc_type(arena1)), vec2(alloc_type(arena2));
vec1.resize(100);

void* data = vec1.data();
vec2 = std::move(vec1);
assert(vec2.data() == data);  // fails
Run Code Online (Sandbox Code Playgroud)

正如在这个答案中所解释的,这是由于向量的移动赋值运算符比较了两个分配器(注意propagate_on_container_move_assignment就是这样std::false_type).由于两个分配器不比较相等(因为它们具有不同的竞技场),目标向量需要分配内存并逐个移动值.

通过将等于运算符更改为,可以实现所需的行为

template <class T1, size_t N1, class T2, size_t N2>
bool operator==(const short_alloc<T1, N1>& x, const short_alloc<T2, N2>& y) noexcept
{
    return N1 == N2 && (&x.a_ == &y.a_ || y.a_.on_heap());
}
Run Code Online (Sandbox Code Playgroud)

其中,on_heap()如果分配没有使用它的竞技场检查.

这个解决方案看起来相当hackish(注意例如,平等不对称),我可以/我会通过这样做射击自己吗?有优雅的解决方案吗?

c++ memory-management allocator move-semantics c++11

11
推荐指数
1
解决办法
476
查看次数

测试类型是否为(智能)指针的通用方法

在我的代码中,我需要测试给模板的类型是否是指针 - 无论是否聪明.根据提升,没有可靠和通用的方法(见这里) - 或者有吗?

到目前为止,我检查以下内容:

  • - 答:可以T转换为void*
  • B:Tget()方法吗?
  • C:有T没有叫做element_type
  • D:get()回来了element_type*吗?

如果(A || B && C && D),那么我得出结论,我的类型必须是某种指针.

这是模板:

template <typename T>
class is_pointer_type
{
    typedef struct { char array[1]; } yes;
    typedef struct { char array[2]; } no;

    template <typename C> static yes test_g(decltype(&C::get));
    template <typename C> static no  test_g(...);

    template <typename C> static yes test_e(typename C::element_type*);
    template <typename C> static …
Run Code Online (Sandbox Code Playgroud)

c++ templates shared-ptr

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

为什么boost :: future <T> :: then()会产生一个新线程?

附加延续时boost::future,继续在新线程中执行:

std::cout << "main: " << boost::this_thread::get_id() << std::endl;

boost::promise<void> p;
boost::future<void> f = p.get_future();
p.set_value();

boost::future<void> f2 = f.then([] (boost::future<void>) {
    std::cout << "future: " << boost::this_thread::get_id() << std::endl;        
});
Run Code Online (Sandbox Code Playgroud)

此代码段输出:

main: 0x7fff7a8d7310
future: 0x101781000
Run Code Online (Sandbox Code Playgroud)

为什么.then()允许这样做,更重要的是,有没有办法来定制这种行为?不要future从返回S ^ promise/ packaged_task/ async不同的表现?

c++ multithreading boost c++11

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

如何存储通用引用

我需要在类中存储通用引用(我确信引用的值将比类更长).这样做有规范的方法吗?

这是我想出的最小例子.它似乎有效,但我不确定我是否做对了.

template <typename F, typename X>
struct binder
{
    template <typename G, typename Y>
    binder(G&& g, Y&& y) : f(std::forward<G>(g)), x(std::forward<Y>(y)) {}

    void operator()() { f(std::forward<X>(x)); }

    F&& f;
    X&& x;
};

template <typename F, typename X>
binder<F&&, X&&> bind(F&& f, X&& x)
{
    return binder<F&&, X&&>(std::forward<F>(f), std::forward<X>(x));
}

void test()
{
    int i = 1;
    const int j = 2;
    auto f = [](int){};

    bind(f, i)();   // X&& is int&
    bind(f, j)();   // X&& is const int&
    bind(f, …
Run Code Online (Sandbox Code Playgroud)

c++ templates perfect-forwarding c++11 universal-reference

7
推荐指数
1
解决办法
958
查看次数

链接调用C++ 11 std :: bind不起作用

调用嵌套std::bind表达式时遇到问题.以下代码演示了此问题.它无法使用libc ++进行编译,但可以使用boost:

#define BOOST 0

#if BOOST
    #include <boost/function.hpp>
    #include <boost/bind.hpp>
    using boost::function;
    using boost::bind;
#else
    #include <functional>
    using std::function;
    using std::bind;
    using std::placeholders::_1;
#endif


int sum(int a, int b) { return a+b; }

// works
template <typename F>
int yeah(F f, int c)
{
    return f(c);
}

// breaks with libc++
template <typename F>
int nope(F f, int c)
{
    return bind(f, c)();
}

// fixes the problem
template <typename F>
int fix1(F f, int c)
{ …
Run Code Online (Sandbox Code Playgroud)

c++ boost-bind c++11 libc++

5
推荐指数
1
解决办法
776
查看次数