2013-08-16 2 views
1

Смотрите ниже код,C++ опция <> и задержка строительства noncopyable объекта

Вопрос: как я могу отложить строительство объекта, который noncopyable, с помощью дополнительного <>.

Я использую 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; 
} 

Я использую г ++, я предполагаю, что это не имеет значения, является ли его 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

Когда вы говорите * не будет компилироваться *, вы должны сообщить нам, что такое сообщение компилятора. Кроме того, если вы используете C++ 03 или C++ 11, самое простое решение может отличаться. –

+0

Причина, по которой он не компилируется, заключается в том, что это будет копирование. И класс не подлежит копированию. –

+0

В зависимости от версии вашего компилятора и параметров, которые вы используете, в C++ 11 класс может быть * move-constructible *, и затем ряд примеров должен компилироваться (в зависимости от того, был ли 'boost :: noncopyable' обновлено, чтобы обеспечить оператор перемещения/оператор перемещения). –

ответ

3

Вы должны in_place непосредственно в объект:

delay_construct = boost::in_place<Type>(params); 

Обратите внимание, что кажется, что повышение не поддержал строительство заводов по умолчанию через (нульарные заводов) до 1,35.

+0

Удивительный, мне кажется таким очевидным сейчас, спасибо большое –

+0

Собственно, это не скомпилируется для меня, когда я добавляю: необязательно no (in_place ()); // BAD –

+0

Я отмечу, что это ответ, но если бы вы могли помочь мне с ошибкой компиляции (см. Выше), это было бы оценено :) –

3

В C++ 14 у нас будет std::optional, который имеет std::optional::emplace. Так вы можете сделать:

std::optional<HardFoo> delay_construct; 
delay_construct.emplace(constructor_arg_1, constructor_arg_2); 
+0

Ницца, мне нравится звук этого! Почему это еще не усилилось? –

 Смежные вопросы

  • Нет связанных вопросов^_^