mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-06 08:46: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
cf444e5309
commit
c9d0a94894
@ -21,20 +21,32 @@ namespace ipc {
|
||||
* \see https://en.cppreference.com/w/cpp/memory/construct_at
|
||||
*/
|
||||
|
||||
template <typename T, typename... A>
|
||||
auto construct(void *p, A &&...args)
|
||||
-> std::enable_if_t<::std::is_constructible<T, A...>::value, T *> {
|
||||
// Overload for zero arguments - use value initialization
|
||||
template <typename T>
|
||||
T* construct(void *p) {
|
||||
#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
|
||||
return ::new (p) T(std::forward<A>(args)...);
|
||||
return ::new (p) T();
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T, typename... A>
|
||||
auto construct(void *p, A &&...args)
|
||||
-> std::enable_if_t<!::std::is_constructible<T, A...>::value, T *> {
|
||||
return ::new (p) T{std::forward<A>(args)...};
|
||||
// Overload for one or more arguments - prefer direct 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 *> {
|
||||
#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