如何用C++模板进一步压缩字符串拼接函数的重载实现?
Can We Reduce the Join Functions to Two Templates?
Absolutely! You can condense your implementation down to two public template functions—one for string-style delimiters (including std::basic_string<T>, const char*, and const wchar_t*) and another for single-character delimiters (char and wchar_t). Here's a clean, efficient way to do it using a private core implementation and C++17's if constexpr for type deduction:
Full Implementation Code
#include <iostream> #include <locale> #include <sstream> #include <string> #include <type_traits> #include <vector> // Private core implementation (does the actual joining logic) template <typename T, typename Arg, typename... Args> std::basic_string<T> join_impl( const std::basic_string<T>& delimiter, const Arg& arg, const Args&... args) { if (!sizeof...(args)) { return arg; } std::basic_ostringstream<T> os; os << arg; static_cast<void>(std::initializer_list<int>{(os << delimiter << args, 0)...}); return os.str(); } // Public template 1: Handles string-style delimiters (basic_string, const char*, const wchar_t*) template <typename Delimiter, typename Arg, typename... Args> auto join(const Delimiter& delimiter, const Arg& arg, const Args&... args) { using namespace std; using DecayDelim = decay_t<Delimiter>; if constexpr (is_same_v<DecayDelim, const char*> || is_same_v<DecayDelim, char*>) { using T = char; return join_impl<T>(basic_string<T>(delimiter), arg, args...); } else if constexpr (is_same_v<DecayDelim, const wchar_t*> || is_same_v<DecayDelim, wchar_t*>) { using T = wchar_t; return join_impl<T>(basic_string<T>(delimiter), arg, args...); } else if constexpr (is_same_v<DecayDelim, basic_string<char>>) { return join_impl<char>(delimiter, arg, args...); } else if constexpr (is_same_v<DecayDelim, basic_string<wchar_t>>) { return join_impl<wchar_t>(delimiter, arg, args...); } else { static_assert(false, "Unsupported delimiter type: only char/wchar_t, const char*/wchar_t*, and std::string/wstring are allowed"); } } // Public template 2: Handles single-character delimiters (char, wchar_t) template <typename T, typename Arg, typename... Args> std::basic_string<T> join(T delimiter, const Arg& arg, const Args&... args) { static_assert(std::is_same_v<T, char> || std::is_same_v<T, wchar_t>, "Single-character delimiter must be char or wchar_t"); return join_impl<T>(std::basic_string<T>(1, delimiter), arg, args...); } int main(int argc, char** argv) { std::wcout.imbue(std::locale("zh_CN.UTF-8")); std::cout << join(' ', "1", "2", "3") << std::endl; std::wcout << join(L' ', L"一", L"二", L"三") << std::endl; std::cout << join(std::string("--"), "1", "2", "3") << std::endl; std::cout << join("--", "1", "2", "3") << std::endl; std::wcout << join(std::wstring(L"--"), L"一", L"二", L"三") << std::endl; std::wcout << join(L"--", L"一", L"二", L"三") << std::endl; return 0; }
How It Works
- Core Logic (
join_impl): This is your original joining logic, untouched. It takes astd::basic_string<T>delimiter and handles string concatenation viastd::basic_ostringstream. - String-Style Delimiters: The first public template uses
if constexprto inspect the delimiter type at compile time:- Converts
const char*/char*tostd::stringand routes tojoin_impl<char> - Converts
const wchar_t*/wchar_t*tostd::wstringand routes tojoin_impl<wchar_t> - Passes existing
std::string/std::wstringdirectly to the matchingjoin_implspecialization
- Converts
- Single-Character Delimiters: The second public template accepts
charorwchar_t, creates a single-characterstd::basic_string<T>, and routes it tojoin_impl. Thestatic_assertensures only valid character types are used.
Key Benefits
- Preserves All Original Functionality: Every test case from your original code will work exactly as before.
- Cleaner Interface: Only two public functions to remember, grouped logically by delimiter type.
- Compile-Time Safety:
static_assertchecks prevent invalid delimiter types from being used accidentally.
Note for C++14 or Earlier
If you're not using C++17, you can replace the if constexpr with SFINAE (using std::enable_if) to achieve the same type deduction. However, if constexpr provides a far more readable and maintainable solution.
内容的提问来源于stack exchange,提问作者Saddle Point
相关产品推荐
相关产品推荐

