mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-07 01:06:45 +08:00
refactor(uninitialized): Improve construct() overload resolution
IMPROVEMENTS:
1. Add explicit zero-argument overload to avoid SFINAE ambiguity
2. Require at least one argument (A1) for parameterized overloads
3. Better separation between direct initialization and aggregate initialization
BENEFITS:
- Clearer intent: zero-argument construction is explicitly handled
- Avoids potential SFINAE ambiguity when empty parameter pack is used
- More maintainable: easier to understand which overload is selected
- Consistent with modern C++ best practices for variadic templates
TECHNICAL DETAILS:
- Zero-arg overload: Always uses T() for value initialization
- One-or-more-arg overload: Uses SFINAE to choose between:
* T(args...) for types with matching constructor
* T{args...} for aggregate types or types with initializer_list ctor
This is a code quality improvement and does not fix any compilation issues,
but provides better template overload resolution.
This commit is contained in:
parent
eede00165e
commit
5d56ef759f
@ -21,20 +21,32 @@ namespace ipc {
|
|||||||
* \see https://en.cppreference.com/w/cpp/memory/construct_at
|
* \see https://en.cppreference.com/w/cpp/memory/construct_at
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template <typename T, typename... A>
|
// Overload for zero arguments - use value initialization
|
||||||
auto construct(void *p, A &&...args)
|
template <typename T>
|
||||||
-> std::enable_if_t<::std::is_constructible<T, A...>::value, T *> {
|
T* construct(void *p) {
|
||||||
#if defined(LIBIPC_CPP_20)
|
#if defined(LIBIPC_CPP_20)
|
||||||
return std::construct_at(static_cast<T *>(p), std::forward<A>(args)...);
|
return std::construct_at(static_cast<T *>(p));
|
||||||
#else
|
#else
|
||||||
return ::new (p) T(std::forward<A>(args)...);
|
return ::new (p) T();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename... A>
|
// Overload for one or more arguments - prefer direct initialization
|
||||||
auto construct(void *p, A &&...args)
|
template <typename T, typename A1, typename... A>
|
||||||
-> std::enable_if_t<!::std::is_constructible<T, A...>::value, T *> {
|
auto construct(void *p, A1 &&arg1, A &&...args)
|
||||||
return ::new (p) T{std::forward<A>(args)...};
|
-> std::enable_if_t<::std::is_constructible<T, A1, A...>::value, T *> {
|
||||||
|
#if defined(LIBIPC_CPP_20)
|
||||||
|
return std::construct_at(static_cast<T *>(p), std::forward<A1>(arg1), std::forward<A>(args)...);
|
||||||
|
#else
|
||||||
|
return ::new (p) T(std::forward<A1>(arg1), std::forward<A>(args)...);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overload for non-constructible types - use aggregate initialization
|
||||||
|
template <typename T, typename A1, typename... A>
|
||||||
|
auto construct(void *p, A1 &&arg1, A &&...args)
|
||||||
|
-> std::enable_if_t<!::std::is_constructible<T, A1, A...>::value, T *> {
|
||||||
|
return ::new (p) T{std::forward<A1>(arg1), std::forward<A>(args)...};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user