见下面的代码,
问题是:如何使用可选的<>来延迟构建不可复制的对象。
我在示例中使用了boost :: optional,虽然我相信它现在也在std :: optional标准中。
是的,我可以使用scoped_ptr<>但是我想在堆栈上分配,而不是堆。
#include <boost/optional.hpp>
#include <boost/utility.hpp>
using namespace boost;
struct HardFoo : noncopyable { };
int main()
{
optional<HardFoo> ok_1( in_place() ); // OK
// optional<HardFoo> no_1( HardFoo() ); // won't compile
optional<HardFoo> delay_construct;
// delay_construct = HardFoo(); // won't compile
// delay_construct = optional<HardFoo>( in_place() ); // won't compile
// delay_construct.swap( optional<HardFoo>( in_place() ) ); // won't compile
return 0;
}
我正在使用g ++,我认为在这种情况下它的C ++ 03或C ++ 11是无关紧要的,因为它是一个基本的设计问题,而不仅仅是代码中的东西。
根据要求,一些错误消息,对于这个,我取消注释:
delay_construct = HardFoo();
$ g++ -g -Wall -o test -I/stuff/boost/ test.cpp
In file included from /stuff/boost/utility.hpp:18:0,
from test.cpp:2:
test.cpp: In instantiation of ‘void boost::optional_detail::optional_base<T>::assign_value(boost::optional_detail::optional_base<T>::argument_type, boost::optional_detail::optional_base<T>::is_not_reference_tag) [with T = HardFoo; boost::optional_detail::optional_base<T>::argument_type = const HardFoo&; boost::optional_detail::optional_base<T>::is_not_reference_tag = mpl_::bool_<false>]’:
/stuff/boost/optional/optional.hpp:307:12: required from ‘void boost::optional_detail::optional_base<T>::assign(boost::optional_detail::optional_base<T>::argument_type) [with T = HardFoo; boost::optional_detail::optional_base<T>::argument_type = const HardFoo&]’
/stuff/boost/optional/optional.hpp:606:9: required from ‘boost::optional<T>& boost::optional<T>::operator=(boost::optional<T>::argument_type) [with T = HardFoo; boost::optional<T> = boost::optional<HardFoo>; boost::optional<T>::argument_type = const HardFoo&]’
test.cpp:14:30: required from here
/stuff/boost/noncopyable.hpp:28:26: error: ‘const boost::noncopyable_::noncopyable& boost::noncopyable_::noncopyable::operator=(const boost::noncopyable_::noncopyable&)’ is private
test.cpp:6:8: error: within this context
In file included from /stuff/boost/optional.hpp:15:0,
from test.cpp:1:
/stuff/boost/optional/optional.hpp:433:69: note: synthesized method ‘HardFoo& HardFoo::operator=(const HardFoo&)’ first required here
In file included from /stuff/boost/utility.hpp:18:0,
from test.cpp:2:
test.cpp: In instantiation of ‘void boost::optional_detail::optional_base<T>::construct(boost::optional_detail::optional_base<T>::argument_type) [with T = HardFoo; boost::optional_detail::optional_base<T>::argument_type = const HardFoo&]’:
/stuff/boost/optional/optional.hpp:308:12: required from ‘void boost::optional_detail::optional_base<T>::assign(boost::optional_detail::optional_base<T>::argument_type) [with T = HardFoo; boost::optional_detail::optional_base<T>::argument_type = const HardFoo&]’
/stuff/boost/optional/optional.hpp:606:9: required from ‘boost::optional<T>& boost::optional<T>::operator=(boost::optional<T>::argument_type) [with T = HardFoo; boost::optional<T> = boost::optional<HardFoo>; boost::optional<T>::argument_type = const HardFoo&]’
test.cpp:14:30: required from here
/stuff/boost/noncopyable.hpp:27:7: error: ‘boost::noncopyable_::noncopyable::noncopyable(const boost::noncopyable_::noncopyable&)’ is private
test.cpp:6:8: error: within this context
In file included from /stuff/boost/optional.hpp:15:0,
from test.cpp:1:
/stuff/boost/optional/optional.hpp:346:8: note: synthesized method ‘HardFoo::HardFoo(const HardFoo&)’ first required here
有一个答案建议直接使用in_place, 它适用于此:
optional<HardFoo> ok( in_place() );
但不是这样:
optional<HardFoo> no( in_place<HardFoo>() ); // BAD
错误消息:
$ g++ -g -Wall -o test -I/stuff/boost/ test.cpp
test.cpp: In function ‘int main()’:
test.cpp:15:44: error: no matching function for call to ‘in_place()’
test.cpp:15:44: note: candidates are:
In file included from /stuff/boost/preprocessor/iteration/detail/iter/forward1.hpp:52:0,
from /stuff/boost/utility/in_place_factory.hpp:24,
from /stuff/boost/optional/optional.hpp:37,
from /stuff/boost/optional.hpp:15,
from test.cpp:1:
/stuff/boost/utility/in_place_factory.hpp:73:1: note: template<class A0> boost::in_place_factory1<A0> boost::in_place(const A0&)
/stuff/boost/utility/in_place_factory.hpp:73:1: note: template argument deduction/substitution failed:
test.cpp:15:44: note: candidate expects 1 argument, 0 provided
In file included from /stuff/boost/preprocessor/iteration/detail/iter/forward1.hpp:57:0,
from /stuff/boost/utility/in_place_factory.hpp:24,
from /stuff/boost/optional/optional.hpp:37,
from /stuff/boost/optional.hpp:15,
from test.cpp:1:
/stuff/boost/utility/in_place_factory.hpp:73:1: note: template<class A0, class A1> boost::in_place_factory2<A0, A1> boost::in_place(const A0&, const A1&)
/stuff/boost/utility/in_place_factory.hpp:73:1: note: template argument deduction/substitution failed:
test.cpp:15:44: note: candidate expects 2 arguments, 0 provided
In file included from /stuff/boost/preprocessor/iteration/detail/iter/forward1.hpp:62:0,
from /stuff/boost/utility/in_place_factory.hpp:24,
from /stuff/boost/optional/optional.hpp:37,
from /stuff/boost/optional.hpp:15,
from test.cpp:1:
答案 0 :(得分:3)
您需要直接插入对象:
delay_construct = boost::in_place<Type>(params);
请注意,直到1.35,boost似乎不支持通过工厂(Nullary工厂)进行默认构建。
答案 1 :(得分:3)
在C ++ 14中,我们将std::optional
,恰好有std::optional::emplace
。所以你可以这样做:
std::optional<HardFoo> delay_construct;
delay_construct.emplace(constructor_arg_1, constructor_arg_2);