尝试 find_if 向量中的 unique_ptr 时出现编译错误
Compilation error when trying to find_if an unique_ptr in a vector
此代码:
#include <memory>
#include <vector>
#include <algorithm>
struct Foo
{
int bar;
Foo(const int val) :
bar(val)
{
}
};
int main() {
std::vector<std::unique_ptr<Foo>> vec;
vec.emplace_back(std::make_unique<Foo>(42));
Foo* ptr = vec.back().get();
auto& it = std::find_if(vec.begin(), vec.end(), [&](std::unique_ptr<Foo>& p)
{
return p.get() == ptr;
});
if (it != vec.end())
{
vec.erase(it);
}
return 0;
}
在 MSVC 中工作正常,但在 GCC 5.1 中出错:
prog.cpp: In function 'int main()':
prog.cpp:19:25: error: invalid initialization of non-const reference of type '__gnu_cxx::__normal_iterator*, std::vector > >&' from an rvalue of type '__gnu_cxx::__normal_iterator*, std::vector > >'
auto& it = std::find_if(vec.begin(), vec.end(), [&](std::unique_ptr& p)
- 哪个编译器有问题?
- 如何从
std::unique_ptr
的 std::vector
中正确删除指针?
gcc 在这里是正确的。您不能用右值初始化左值引用,而您这样做是为了 it
对迭代器的引用(std::find_if
returns 一个右值)
auto& it = std::find_if(vec.begin(), vec.end(), [&](std::unique_ptr<Foo>& p)
^
要么把它变成一个对象:
auto it = std::find_if(vec.begin(), vec.end(), [&](std::unique_ptr<Foo>& p)
或常量引用:
auto const& it = std::find_if(vec.begin(), vec.end(), [&](std::unique_ptr<Foo>& p)
除此之外,您从向量中删除元素的代码是正确的
如果您打开 4 级警告,VS2015 将发出正在使用非标准扩展的警告 /W4
:
warning C4239: nonstandard extension used:
note: A non-const reference may only be bound to an lvalue
#pragma warning( push, 3 )
#include <memory>
#include <vector>
#include <algorithm>
#pragma warning( pop )
#pragma warning( disable : 4710 )
struct Foo
{
int bar;
Foo(const int val) :
bar(val)
{
}
};
int main() {
std::vector<std::unique_ptr<Foo>> vec;
vec.emplace_back(std::make_unique<Foo>(42));
Foo* ptr = vec.back().get();
auto& it = std::find_if(vec.begin(), vec.end(), [&](std::unique_ptr<Foo>& p)
{
return p.get() == ptr;
});
if(it != vec.end())
{
vec.erase(it);
}
return 0;
}
生产:
1>c:\users\flatmouse\documents\visual studio 2015\projects\project79\project79\source.cpp(25): warning C4239: nonstandard extension used: 'initializing': conversion from 'std::_Vector_iterator<std::_Vector_val<std::_Simple_types<std::unique_ptr<Foo,std::default_delete<_Ty>>>>>' to 'std::_Vector_iterator<std::_Vector_val<std::_Simple_types<std::unique_ptr<Foo,std::default_delete<_Ty>>>>> &'
1> with
1> [
1> _Ty=Foo
1> ]
1> c:\users\flatmouse\documents\visual studio 2015\projects\project79\project79\source.cpp(25): note: A non-const reference may only be bound to an lvalue
此代码:
#include <memory>
#include <vector>
#include <algorithm>
struct Foo
{
int bar;
Foo(const int val) :
bar(val)
{
}
};
int main() {
std::vector<std::unique_ptr<Foo>> vec;
vec.emplace_back(std::make_unique<Foo>(42));
Foo* ptr = vec.back().get();
auto& it = std::find_if(vec.begin(), vec.end(), [&](std::unique_ptr<Foo>& p)
{
return p.get() == ptr;
});
if (it != vec.end())
{
vec.erase(it);
}
return 0;
}
在 MSVC 中工作正常,但在 GCC 5.1 中出错:
prog.cpp: In function 'int main()':
prog.cpp:19:25: error: invalid initialization of non-const reference of type '__gnu_cxx::__normal_iterator*, std::vector > >&' from an rvalue of type '__gnu_cxx::__normal_iterator*, std::vector > >' auto& it = std::find_if(vec.begin(), vec.end(), [&](std::unique_ptr& p)
- 哪个编译器有问题?
- 如何从
std::unique_ptr
的std::vector
中正确删除指针?
gcc 在这里是正确的。您不能用右值初始化左值引用,而您这样做是为了 it
对迭代器的引用(std::find_if
returns 一个右值)
auto& it = std::find_if(vec.begin(), vec.end(), [&](std::unique_ptr<Foo>& p)
^
要么把它变成一个对象:
auto it = std::find_if(vec.begin(), vec.end(), [&](std::unique_ptr<Foo>& p)
或常量引用:
auto const& it = std::find_if(vec.begin(), vec.end(), [&](std::unique_ptr<Foo>& p)
除此之外,您从向量中删除元素的代码是正确的
如果您打开 4 级警告,VS2015 将发出正在使用非标准扩展的警告 /W4
:
warning C4239: nonstandard extension used:
note: A non-const reference may only be bound to an lvalue
#pragma warning( push, 3 )
#include <memory>
#include <vector>
#include <algorithm>
#pragma warning( pop )
#pragma warning( disable : 4710 )
struct Foo
{
int bar;
Foo(const int val) :
bar(val)
{
}
};
int main() {
std::vector<std::unique_ptr<Foo>> vec;
vec.emplace_back(std::make_unique<Foo>(42));
Foo* ptr = vec.back().get();
auto& it = std::find_if(vec.begin(), vec.end(), [&](std::unique_ptr<Foo>& p)
{
return p.get() == ptr;
});
if(it != vec.end())
{
vec.erase(it);
}
return 0;
}
生产:
1>c:\users\flatmouse\documents\visual studio 2015\projects\project79\project79\source.cpp(25): warning C4239: nonstandard extension used: 'initializing': conversion from 'std::_Vector_iterator<std::_Vector_val<std::_Simple_types<std::unique_ptr<Foo,std::default_delete<_Ty>>>>>' to 'std::_Vector_iterator<std::_Vector_val<std::_Simple_types<std::unique_ptr<Foo,std::default_delete<_Ty>>>>> &'
1> with
1> [
1> _Ty=Foo
1> ]
1> c:\users\flatmouse\documents\visual studio 2015\projects\project79\project79\source.cpp(25): note: A non-const reference may only be bound to an lvalue