重构doThings函数:基于类型列表内部创建元组向量
Alright, let's break down how to refactor your doThings function exactly as you want—hiding the tuple/vector creation logic inside the function, so callers only need to pass a type list and any variables they want to tie (if needed).
First, the Core Idea
Instead of making callers construct boost::fusion::vector_tie or make_tuple themselves, we'll shift that work into doThings. We'll use template parameters to define the type list, and add overloads to handle both tied variables (your existing vector_tie use case) and default-constructed tuples (like your empty make_tuple() call).
Refactored Code
Let's start with the most straightforward version using variadic templates for the type list:
Overload 1: Bind Existing Variables (Replaces vector_tie Calls)
This overload takes the type list as template parameters and the variables to tie as function arguments:
template <typename... ColumnTypes> void doThings(ColumnTypes&&... vars) { // Create the fusion vector_tie internally—callers don't need to see this auto cols = boost::fusion::vector_tie(std::forward<ColumnTypes>(vars)...); // Your existing cols processing logic goes right here, unchanged // ... (your original internal handling) }
Overload 2: Default-Constructed Tuples (Replaces make_tuple() Calls)
This handles cases where you want to create a tuple (empty or with default-constructed values) without tying existing variables:
// Empty tuple case template <typename... ColumnTypes> typename std::enable_if<sizeof...(ColumnTypes) == 0>::type doThings() { auto cols = boost::fusion::make_tuple(); // Existing processing logic } // Non-empty default-constructed tuple case template <typename... ColumnTypes> typename std::enable_if<sizeof...(ColumnTypes) != 0>::type doThings() { auto cols = boost::fusion::make_tuple(ColumnTypes{}...); // Existing processing logic }
Updated Call Sites
Now your calls become way cleaner and don't expose the Fusion details:
- Instead of
doThings(boost::fusion::vector_tie(anyVar1, anyVar2));:// Explicit type list matches the variables' types doThings<decltype(anyVar1), decltype(anyVar2)>(anyVar1, anyVar2); - For the empty tuple call
doThings(boost::fusion::make_tuple());:doThings<>(); - If you want a tuple with default-constructed
intanddoublevalues:doThings<int, double>();
Alternative: Using Boost.MPL Type Lists
If you prefer passing a single type list (instead of variadic template params), you can use Boost.MPL's vector for more explicit type grouping:
#include <boost/mpl/vector.hpp> #include <boost/fusion/mpl.hpp> // Default-constructed tuple from MPL type list template <typename TypeList> void doThings() { auto cols = boost::fusion::result_of::as_tuple<TypeList>::type{}; // Processing logic here } // Tied variables matching the MPL type list (with type safety check) template <typename TypeList, typename... Vars> void doThings(Vars&&... vars) { // Ensure the variable types match the type list static_assert(std::is_same_v<boost::mpl::vector<std::decay_t<Vars>...>, TypeList>, "Variable types must exactly match the provided type list"); auto cols = boost::fusion::vector_tie(std::forward<Vars>(vars)...); // Processing logic here }
Calls for this version look like:
// Default-constructed int + double tuple doThings<boost::mpl::vector<int, double>>(); // Tie existing variables to the type list doThings<boost::mpl::vector<int, double>>(anyIntVar, anyDoubleVar);
Key Benefits of This Refactor
- Encapsulation: All Fusion-specific tuple/vector creation is hidden inside
doThings—callers don't need to know aboutvector_tieormake_tuple. - Type Safety: Explicit type lists prevent accidental type mismatches in caller code.
- Flexibility: We cover all your original use cases (tied variables, empty tuples, default-constructed tuples) with clean, readable calls.
内容的提问来源于stack exchange,提问作者Hardwired

