实现编译时“static-if";容器中不同字符串类型的逻辑 [英] Implementing a compile-time "static-if" logic for different string types in a container

查看:15
本文介绍了实现编译时“static-if";容器中不同字符串类型的逻辑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'd like to write a function template that operates on a container of strings, for example a std::vector.

我想用相同的模板函数同时支持 CStringstd::wstring.

I'd like to support both CString and std::wstring with the same template function.

问题是 CString 和 wstring 有不同的接口,例如要获取 CString 的长度",您调用 GetLength() 方法,而不是 wstring 你调用 size()length().

The problem is that CString and wstring have different interfaces, for example to get the "length" of a CString, you call the GetLength() method, instead for wstring you call size() or length().

如果我们在 C++ 中有一个 "static if" 功能,我可以编写如下内容:

If we had a "static if" feature in C++, I could write something like:

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 工具来实现这一目标?

Is there some template programming technique to achieve this goal with currently available C++11/14 tools?

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

PS
I know it's possible to write a couple of DoSomething() overloads with vector<CString> and vector<wstring>, but that's not the point of the question.
Moreover, I'd like this function template to work for any container on which you can iterate using a range-for loop.

推荐答案

#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);
    }
}

演示

这篇关于实现编译时“static-if";容器中不同字符串类型的逻辑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆