구체적으로 : 직접 목록 초기화 (cppreference.com(3)).std :: make_shared/std :: make_unique가 목록 초기화를 사용하지 않는 이유가 있습니까?
모두 std::make_shared
및 균일 초기화 기능이 C++ 11에 소개되었다. 따라서 힙에 객체를 할당 할 때 집합 초기화을 사용할 수 있습니다 : new Foo{1, "2", 3.0f}
. 이는 집계, 포드 등과 같은 생성자가없는 객체를 직접 초기화하는 좋은 방법입니다.
캐주얼 문자를 구조로 선언하는 등의 실제 시나리오를 효율적으로 인수 집합을 제공합니다. 람다는 내 경험에 매우 일반적되었다 :
여기void foo()
{
struct LambdaArgs
{
std::string arg1;
std::string arg2;
std::string arg3;
};
auto args = std::make_shared<LambdaArgs>(LambdaArgs{"1", "2", "3"});
auto lambda = [args] {
/// ...
};
/// Use lambda
/// ...
}
std::make_shared
는 일반적으로 구현되기 때문에 auto args = std::make_shared<LambdaArgs>("1", "2", "3");
가 좋은 있지만 작동하지 않을 수 whould :
template<typename T, typename... Args>
std::shared_ptr<T> make_shared(Args && ...args)
{
return std::shared_ptr<T>(new T(std::forward<Args>(args)...));
}
,536,
그래서 우리는 auto args = std::make_shared<LambdaArgs>(LambdaArgs{"1", "2", "3"});
에 붙어 있습니다.
std::make_shared
으로 해결해야하는 문제는 생성자가없는 개체에 대해서도 계속 유지됩니다. 그리고 해결 방법은 심미적이지 않을뿐만 아니라 덜 효율적입니다.
또 다른 감독입니까, 아니면이 선택을 방어해야 할 몇 가지 이유가 있습니까? 특히, 목록 초기화 솔루션에 어떤 함정이있을 수 있습니까? std::make_unique
은 나중에 소개되었으므로 C++ 14에 왜 같은 패턴을 따르는가?
당신의 질문에 대한 대답은 아니지만 해결 방법 : 일반 구조체 대신 튜플을 사용하는 경우 적절한 생성자가 제공되며 더 간결합니다 :'LambdaArgs = std :: tuple'; –
Frank
'std :: make_shared' 문제는 객체 생성 후 shared_ptr이 소유권을 갖기 전에 예외가 발생하면 모든 것이 올바르게 정리되었는지 확인하는 문제입니다. 이것으로 사소한 감독처럼 보입니다. – Kevin
당신은이 흥미로운 것을 발견 할 수 있습니다 : http://stackoverflow.com/questions/24234480/stdmake-shared-with-stdinitializer-list – marcinj