相关疑难解决方法(0)

编译器错误C3493:无法隐式捕获'func',因为未指定默认捕获模式

你能帮我解决这个编译错误吗?

template<class T>
static void ComputeGenericDropCount(function<void(Npc *, int)> func)
{
    T::ForEach([](T *what) {
        Npc *npc = Npc::Find(what->sourceId);

        if(npc)
            func(npc, what->itemCount); // <<<<<<< ERROR HERE
            // Error    1   error C3493: 'func' cannot be implicitly captured because no default capture mode has been specified

    });
}

static void PreComputeNStar()
{
     // ...
    ComputeGenericDropCount<DropSkinningNpcCount>([](Npc *npc, int i) { npc->nSkinned += i; });
    ComputeGenericDropCount<DropHerbGatheringNpcCount>([](Npc *npc, int i) { npc->nGathered += i; });
    ComputeGenericDropCount<DropMiningNpcCount>([](Npc *npc, int i) { npc->nMined += i; });
}
Run Code Online (Sandbox Code Playgroud)

我不明白为什么它给我错误,我不知道如何解决它.ComputeGenericDropCount(auto …

c++ compiler-errors visual-studio-2010 visual-studio c++11

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

防止不必要的C++仿函数对象副本

我有一个类,它可以累积有关一组对象的信息,可以作为仿函数或输出迭代器.这允许我做以下事情:

std::vector<Foo> v;
Foo const x = std::for_each(v.begin(), v.end(), Joiner<Foo>());
Run Code Online (Sandbox Code Playgroud)

Foo const x = std::copy(v.begin(), v.end(), Joiner<Foo>());
Run Code Online (Sandbox Code Playgroud)

现在,理论上,编译器应该能够使用复制省略和返回值优化,以便只Joiner需要创建一个对象.然而,在实践中,该函数会生成一个操作副本,然后将其复制回结果,即使在完全优化的构建中也是如此.

如果我将仿函数创建为左值,则编译器会创建两个额外的副本而不是一个副本:

Joiner<Foo> joiner;
Foo const x = std::copy(v.begin(), v.end(), joiner);
Run Code Online (Sandbox Code Playgroud)

如果我笨拙地强制将模板类型强制转换为引用,它会传入引用,但无论如何都要复制它并返回对(现在已销毁的)临时副本的悬空引用:

x = std::copy<Container::const_iterator, Joiner<Foo>&>(...));
Run Code Online (Sandbox Code Playgroud)

我可以通过在样式的仿函数中使用对状态的引用而不是状态本身来使副本变得便宜std::inserter,从而导致类似这样的事情:

Foo output;
std::copy(v.begin(), v.end(), Joiner<Foo>(output));
Run Code Online (Sandbox Code Playgroud)

但是这使得不可能使用不可变对象的"功能"风格,而且通常不那么好.

有没有办法鼓励编译器忽略临时副本,或者让它一直通过引用并返回相同的引用?

c++ optimization templates

16
推荐指数
1
解决办法
3602
查看次数