단순한 평범함의 환상적인 아이디어를 기반으로 "현재 위치에서 개체 재활용"해킹을 수행하는 기능을 구현했습니다 배정 별 배정 - 새 예 GotW # 23에 표시되고 # 28에서 참조된다.전달이 "자유주의"가되지 못하도록 함
(예, 예, 알고 있습니다. 그러나 실제로 많은 메시지를 처리하는 응용 프로그램에서이 해킹이 매우 눈에 띄는 최적화로 유용하게 사용되었습니다.
코드는 3.5 ++ 연타에 경고없이 컴파일하고 "잘 작동"하지만 accidentially 일어날 수 있으며 이는이 바람직하지 않을 수있는 몇 가지 암시 적 변환 할 수 있습니다로 다소 내 의견으로는 너무 진보적이다 :
#include <type_traits>
template<typename T>
typename std::enable_if<std::is_nothrow_move_constructible<T>::value, T&>::type
recycle(T& obj, T&& other) noexcept
{ obj.~T(); new (&obj) T(other); return obj; }
template<typename T, typename... A>
typename std::enable_if<std::is_nothrow_constructible<T>::value && std::is_nothrow_move_constructible<T>::value, T&>::type
recycle(T& obj, A&&... arg) noexcept
{ obj.~T(); new (&obj) T(arg...); return obj; }
int main()
{
struct foo
{
foo() noexcept {}
explicit foo(float) noexcept {}
};
foo b;
recycle(b, foo()); // OK, calls #1, move-constructing from default temporary
recycle(b, foo(1.0f)); // OK, as above, but non-default temporary
recycle(b, 5.0f); // OK, calls #2, forwarding and move-constructing
recycle(b, 5.0); // succeeds calling #2 (undesired implicit double --> float conversion)
recycle(b, 5); // succeeds calling #2 (undesired implicit int ---> float conversion)
recycle(b, b); // succeeds, but should probably fail a runtime check (undefined behavior)
return 0;
}
을 사실을 템플릿 매개 변수 팩 catc가 필요하기 때문에 예상하지 못할 때 일부 컴파일은 올바르게 컴파일됩니다. hes "everything"이라고 말하지만, 나는 foo
의 생성자가 explicit
이고 템플릿이 그것을 호출해야하기 때문에 alltogether가 어떻게 작동하는지 아직도 놀랍다. 나는 clang ++없이 경고를 내뿜 지 않고 정수와 double을 어떻게 float으로 변환 할 수 있을지 확신하지 못한다.
이것은 내가 explicit
키워드가 생성자에 대해하는 일에 대해 뭔가 잘못되었다고 생각하는지 궁금하게 만듭니다.
자체 할당 (정의되지 않은 동작을 유발 함)은 처음에는 심각한 두뇌 실패를 보여주기 때문에 자체적으로 객체를 재활용하려고 시도한 이후로 나에게 별다른 문제가 아닙니다 (따라서 런타임 검사를 추가하지 않기로 결정했습니다. 그럴 경우), 암시 적으로 변환 가능한 매개 변수가있는 함수를 우연히 호출하는 것은 매우 쉽게 발생할 수있는 일이며 가능하다면 컴파일러 오류로 catch하고 싶습니다.
기본적으로 내가 필요한 것은 get_constructor_args<T>
과 같은 것이고 enable_if
은 is_convertible
입니다. 아니면 뭔가 ... 개념?
C++ 11 (또는 C++ 14)을 사용하여 이런 종류의 작업을 수행 할 수 있습니까?
[좁은 변환을 잡으려면'{}'를 사용하십시오.] (http://coliru.stacked-crooked.com/a/ea5c188e4ab2b0b1). 또한,'other'가 lvalue (이름을 가지고 있기 때문에)의 첫 번째'recycle'은 항상 복사됩니다. 'std :: forward'를 사용하면 임시로 전달 될 때 이동하게됩니다. 마지막으로,'recycle (b, 5.0f);은 아무 것도 움직이지 않는다. –
''recycle (T &, T &&)'는 최적화 대 이동 할당이라고 생각하기가 어렵습니다. 이동 할당이 끔찍한 경우가 아니면. – Casey