我想编写一个对字符串容器(例如std::vector)进行操作的函数模板。

我想使用相同的模板功能同时支持CStringstd::wstring

问题在于CString和wstring具有不同的接口(interface),例如,要获取CString的“长度”,您可以调用GetLength()方法,而对于wstring,您可以调用size()length()

如果我们在C++中具有“static if”功能,那么我可以编写以下内容:

template <typename ContainerOfStrings>
void DoSomething(const ContainerOfStrings& strings)
{
    for (const auto & s : strings)
    {
        static_if(strings::value_type is CString)
        {
            // Use the CString interface
        }
        static_else_if(strings::value_type is wstring)
        {
            // Use the wstring interface
        }
    }
}

是否有一些模板编程技术可以使用当前可用的C++ 11/14工具来实现此目标?

PS
我知道可以用DoSomething()vector<CString>编写几个vector<wstring>重载,但这不是问题的重点。
此外,我希望此函数模板可用于您可以使用range-for循环在其上进行迭代的任何容器。

最佳答案

#include <type_traits>

template <typename T, typename F>
auto static_if(std::true_type, T t, F f) { return t; }

template <typename T, typename F>
auto static_if(std::false_type, T t, F f) { return f; }

template <bool B, typename T, typename F>
auto static_if(T t, F f) { return static_if(std::integral_constant<bool, B>{}, t, f); }

template <bool B, typename T>
auto static_if(T t) { return static_if(std::integral_constant<bool, B>{}, t, [](auto&&...){}); }

测试:
template <typename ContainerOfStrings>
void DoSomething(const ContainerOfStrings& strings)
{
    for (const auto & s : strings)
    {
        static_if<std::is_same<typename ContainerOfStrings::value_type, CString>{}>
        ([&](auto& ss)
        {
            // Use the CString interface
            ss.GetLength();
        })(s);

        static_if<std::is_same<typename ContainerOfStrings::value_type, wstring>{}>
        ([&](auto& ss)
        {
            // Use the wstring interface
            ss.size();
        })(s);
    }
}

DEMO

关于c++ - 为容器中的不同字符串类型实现编译时的 “static-if”逻辑,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37617677/

10-12 19:23