From 6d1a7199ee7ff4f8cdd2dcb82e23351346494c61 Mon Sep 17 00:00:00 2001 From: Lawrence Mitchell Date: Fri, 2 May 2025 08:48:29 +0000 Subject: [PATCH] Move Buffer::overloaded dispatch helper to top level GCC versions prior to v12.0 had a bug in class template argument deduction rules: they were incorrectly required to live at namespace scope. For example, the following definition struct Foo { template struct overloaded : Ts... { using Ts::operator()...; }; template overloaded(Ts...) -> overloaded; }; Produces the compile error error: deduction guide 'Foo::overloaded(Ts ...) -> Foo::overloaded' must be declared at namespace scope 6 | overloaded(Ts...) -> overloaded; | ^~~~~~~~~~ In contrast, both clang, and later versions of GCC, correctly accept this definition. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79501 and https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100983 for details. Since we still advertise support for GCC 11, and pip-based devcontainer builds use GCC 11, work around this bug by moving the overloaded dispatch helper (used in methods that visit the variant storage) to a top-level anonymous namespace. --- cpp/include/rapidsmpf/buffer/buffer.hpp | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/cpp/include/rapidsmpf/buffer/buffer.hpp b/cpp/include/rapidsmpf/buffer/buffer.hpp index 3830f555..1dd0277b 100644 --- a/cpp/include/rapidsmpf/buffer/buffer.hpp +++ b/cpp/include/rapidsmpf/buffer/buffer.hpp @@ -26,6 +26,18 @@ enum class MemoryType : int { /// @brief Array of all the different memory types. constexpr std::array MEMORY_TYPES{{MemoryType::DEVICE, MemoryType::HOST}}; +namespace { +/// @brief Helper for overloaded lambdas using std::visit. +template +struct overloaded : Ts... { + using Ts::operator()...; +}; +/// @brief Explicit deduction guide +template +overloaded(Ts...) -> overloaded; + +} // namespace + /** * @brief Buffer representing device or host memory. * @@ -48,15 +60,6 @@ class Buffer { */ using StorageT = std::variant; - /// @brief Helper for overloaded lambdas for Storage types in StorageT - template - struct overloaded : Ts... { - using Ts::operator()...; - }; - /// @brief Explicit deduction guide - template - overloaded(Ts...) -> overloaded; - /** * @brief Access the underlying host memory buffer (const). * @@ -112,7 +115,7 @@ class Buffer { * * @throws std::logic_error if the buffer is not initialized. */ - MemoryType constexpr mem_type() const { + [[nodiscard]] MemoryType constexpr mem_type() const { return std::visit( overloaded{ [](const HostStorageT&) -> MemoryType { return MemoryType::HOST; },