std :: vector의 집계 목록 초기화는 이동 이 더 적합 할 때 복사 초기화를 수행 한다는 것을 알았습니다 . 동시에 여러 emplace_backs가 원하는 것을 수행합니다.
나는 템플릿 함수를 작성하는이 불완전한 해결책을 생각 해낼 수 있었다 init_emplace_vector
. 그러나 명시 적이 지 않은 단일 값 생성자에 대해서만 최적입니다 .
template <typename T, typename... Args>
std::vector<T> init_emplace_vector(Args&&... args)
{
std::vector<T> vec;
vec.reserve(sizeof...(Args)); // by suggestion from user: eerorika
(vec.emplace_back(std::forward<Args>(args)), ...); // C++17
return vec;
}
질문
std :: vector를 최대한 효율적으로 초기화 하려면 emplace_back을 사용해야 합니까?
// an integer passed to large is actually the size of the resource
std::vector<large> v_init {
1000, // instance of class "large" is copied
1001, // copied
1002, // copied
};
std::vector<large> v_emplaced;
v_emplaced.emplace_back(1000); // moved
v_emplaced.emplace_back(1001); // moved
v_emplaced.emplace_back(1002); // moved
std::vector<large> v_init_emplace = init_emplace_vector<large>(
1000, // moved
1001, // moved
1002 // moved
);
산출
클래스 large
는 복사 / 이동 (아래 구현)에 대한 정보를 생성하므로 내 프로그램의 출력은 다음과 같습니다.
- initializer
large copy
large copy
large copy
- emplace_back
large move
large move
large move
- init_emplace_vector
large move
large move
large move
대규모 클래스 구현
내 구현 large
은 단순히 복사 / 이동에 대해 경고하는 큰 리소스를 보유하는 복사 가능한 / 이동 가능한 유형입니다.
struct large
{
large(std::size_t size) : size(size), data(new int[size]) {}
large(const large& rhs) : size(rhs.size), data(new int[rhs.size])
{
std::copy(rhs.data, rhs.data + rhs.size, data);
std::puts("large copy");
}
large(large&& rhs) noexcept : size(rhs.size), data(rhs.data)
{
rhs.size = 0;
rhs.data = nullptr;
std::puts("large move");
}
large& operator=(large rhs) noexcept
{
std::swap(*this, rhs);
return *this;
}
~large() { delete[] data; }
int* data;
std::size_t size;
};
편집하다
예약을 사용하면 복사 또는 이동이 없습니다. large::large(std::size_t)
생성자 만 호출됩니다. 진정한 직장.
답변
std :: vector를 집계 초기화 할 수 있습니까?
아니요 std::vector
. 집계가 아니므로 집계 초기화 할 수 없습니다.
대신 목록 초기화를 의미 할 수 있습니다.
요소를 완벽하게 전달하여 std :: vector를 [목록 초기화] 할 수 있습니까 ?
아니요. 목록 초기화는 std::initializer_list
생성자를 사용 std::initializer_list
하고 인수를 복사합니다.
당신 init_emplace_vector
이 요소를 emplacing 전에 메모리를 확보함으로써 개선 될 수 있지만 나타난다는 괜찮은 솔루션이 될 수 있습니다.