使用 std::bind Visual Studio 中的编译器错误 C3538

Compiler error C3538 in Visual Studio using std::bind

我在编译以下小代码片段时遇到问题。 Visual Studio2015在remover的类型推导上有问题。有人可以向我解释为什么以及如何解决此错误吗?

我的想法是创建一个可重复使用的函数,删除某个用户可定义谓词下给定 STL 容器中第一次出现的值。

#include <algorithm>
#include <iostream>
#include <iterator>
#include <functional>
#include <vector>

template<typename T>
auto removeOnlyOnce = [](std::vector<T>& v, const std::function<bool(const T&)>& pred) {
    auto iter = std::find_if(v.begin(), v.end(), pred);
    if (iter != v.end()) {
        v.erase(iter);
    }
};

int main(int argc, char** args) {
    std::vector<int> v{ 1,2,3,4,2,2,3 };

    // Works
    std::function<bool(const int&)> isTwoPred = [](int x) { return x == 2; };
    removeOnlyOnce<int>(v, isTwoPred);

    // Also works
    removeOnlyOnce<int>(v, [](const int x)->bool { return x == 2; });

    // Gives compile error: C3538
    // auto remover = std::bind(removeOnlyOnce<int>, v, std::placeholders::_1);
    // remover([](const int x)->bool { return true; });

    std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, " "));
}

编译器发出以下警告:

main.cpp(26): error C3538: In einer Deklaratorliste muss "auto" immer in denselben Typ hergeleitet werden.
main.cpp(26): note: kann "<lambda_d00b55a1f2cac59f0efd4a81f45edea3>" sein
main.cpp(26): note: oder "std::_Binder<std::_Unforced,<lambda_d00b55a1f2cac59f0efd4a81f45edea3> &,std::vector<int,std::allocator<_Ty>> &,const std::_Ph<1> &>"
    with
    [
        _Ty=int
    ]

使用 Wandbox 和选项 C++11 进行编译会出现以下警告,这可能很重要:

prog.cc:8:6: warning: variable templates are a C++14 extension [-Wc++14-extensions]
auto removeOnlyOnce = [](std::vector<T>& v, const std::function<bool(const T&)>& pred) {
     ^
1 warning generated.

这个 lambda 不是本地的。请省略 [&] 中的 & 应该没问题。也许有点神秘,我写的是:换句话说,你没有要捕获的 this