나는 이동과 lvalue 의미론에있어서 꽤 새로운 것이다. 그리고 내가 잘못하고 있다는 인상을받습니다. 여기 한번 FunctContainer
을 쓸 수 있기를 원하는 코드가 구현됩니다 fc1
에 저장된 함수의 수명이 f
의 하나는 수명이되도록lvalue를 참조하고 rvalue 인 경우 복사본을 만듭니다. 즉 rvalue를 영구화합니다.
std::function<double(double)> f = [](double x){return (x * x - 1); };
FunctContainer fc1 = FunctContainer(f);
FunctContainer fc2 = FunctContainer([](double x){return (x * x - 1); });
내가 FunctContainer
년대의 ctors을 작성하려면 포함 된 기능의 fc2
은 fc2
자체의 수명입니다.
나는 (아래 참조) 필자는 정말로 만족스럽지 않지만 (나는 잘못 알고있다).
이것은 올바른 C++이지만 잘못된 동작입니다. f_
이 rvalue 일 때 생성자를 호출 한 후 f_
이 만료됩니다.
class FunctContainerWRONG{
public:
IntegrandNotProjecting(const std::function<double(double)>& function)
: f_(function){}
IntegrandNotProjecting(const std::function<double(double)>&& function)
: f_(std::move(function)){}
const std::function<double(double)>& f_;
private:
};
이 나 한테 끔찍한 외모와 아마 올바른 C하지 ++하지만 원하는 동작이 어떻게 생겼는지 의사에 설명하기위한 것입니다. 나는 새로운 객체를 constuct을 피하려고하고 난 그냥 내 객체를하게 할 수있는 경우 "계속"
class FunctContainer{
public:
FunctContainer(const std::function<double(double)>& function)
: f_p(nullptr),
f_(function){}
FunctContainer(const std::function<double(double)>&& function)
: f_p()std::make_shared<std::function<double(double)>>(function)),
f_(*f_p){}
private:
std::shared_ptr<std::function<double(double)>> f_p;
const std::function<double(double)>& f_;
};
그래서 (일관성 소유권 및 수명 관리 이외의) 마지막 예와 실제로 어떤 문제가 있는지? 소유권은 어쨌든 공유되지 않기 때문에 'unique_ptr'을 사용할 수 있습니다. – VTT
@VTT 마지막 예제에서 싫어하는 것은 함수가 rvalue 인 경우 복사본을 만들고 싶지만 컴파일러가이를 최적화하도록 명시 적으로 선호하는 것입니다. 또한, 만약 당신이 rvalue 있고 다른 경우에 공유 포인터가 고유해야합니다. 이것은 하나 이상의 포인터가 필요하다는 것을 의미하며이 포인터를 관리합니다. – jimifiki