Mr.*_*C64 12 c++ containers templates compile-time c++11
我想编写一个函数模板,对一个字符串容器进行操作,例如a std::vector
.
我想支持两者CString
并std::wstring
使用相同的模板功能.
问题是,CString
wstring有不同的接口,例如获取a的"长度" CString
,你调用GetLength()
方法,而不是你调用的wstring size()
或length()
.
如果我们在C++中有一个"静态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
}
}
}
Run Code Online (Sandbox Code Playgroud)
是否有一些模板编程技术可以使用当前可用的C++ 11/14工具实现这一目标?
PS
我知道可以DoSomething()
用vector<CString>
和编写几个重载vector<wstring>
,但这不是问题的关键.
此外,我希望这个函数模板适用于任何可以使用range-for循环进行迭代的容器.
Pio*_*cki 19
#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&&...){}); }
Run Code Online (Sandbox Code Playgroud)
测试:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
您可以提供满足您需要的功能重载:
size_t getSize(const std::string& str)
{
return str.size();
}
size_t getSize(const CString& str)
{
return str.GetLength();
}
template <typename ContainerOfStrings>
void DoSomething(const ContainerOfStrings& strings)
{
for (const auto & s : strings)
{
...
auto size = getSize(s);
...
}
}
Run Code Online (Sandbox Code Playgroud)