Vit*_*meo 7 c++ static templates if-statement c++11
我有一个扫描用户文件系统的函数,用路径填充向量,然后对其进行排序.由于用户应该能够在编译时决定是否要求向量排序,我使用模板和帮助程序类来代替非常期望(但不存在)的"静态if".
考虑以下代码:
enum class Sort{Alphabetic, Unsorted};
template<Sort TS> struct SortHelper;
template<> struct SortHelper<Sort::Alphabetic>
{
static void sort(vector<string>& mTarget) { sort(begin(mTarget), end(mTarget)); }
};
template<> struct SortHelper<Sort::Unsorted>
{
static void sort(vector<string>&) { }
};
template<Sort TS> struct DoSomethingHelper
{
static void(vector<string>& mTarget)
{
// do something with mTarget
SortHelper<TS>::sort(mTarget);
}
};
Run Code Online (Sandbox Code Playgroud)
我上面编写的代码与原始代码相比有了很大的简化,它采用了多个模板参数,允许用户在编译时进一步自定义函数的结果.
是否有使用所有这些帮助程序类的替代方法?它变得非常混乱,难以阅读.
理想情况下,这是我想写的:
enum class Sort{Alphabetic, Unsorted};
template<Sort TS> struct DoSomethingHelper
{
static void(vector<string>& mTarget)
{
// do something with mTarget
static_if(TS == Sort::Unsorted) { /* do nothing */ }
static_if(TS == Sort::Alphabetic) { sort(begin(mTarget), end(mTarget)); }
}
};
Run Code Online (Sandbox Code Playgroud)
sya*_*yam 17
由于您的值在编译时已知(非模板类型参数),因此您可以完美地编写"正常" if
:
template<Sort TS>
void someFunction(vector<string>& mTarget)
{
if (TS == Sort::Alphabetic) { sort(begin(mTarget), end(mTarget)); }
// else if (TS == Sort::Unsorted) {}
}
Run Code Online (Sandbox Code Playgroud)
编译器将执行常量折叠和死代码消除(当然,如果启用了这些优化),结果将与使用假设的结果完全相同static_if
.
Mat*_* M. 11
我担心对使用的误解static_if
.
当然你可以使用static_if
(或者你想要的任何技巧)尝试进行一些优化,但这不是它的第一个目标.
第一个目标static_if
是语义.让我来证明这一点std::advance
.典型的实现std::advance
将使用类型开关在编译时选择O(1)实现(用于随机访问迭代器)和O(n)实现(用于其他实现):
template <typename It, typename D>
void advance_impl(It& it, D d, random_access_iterator_tag)
{
it += d;
}
template <typename It, typename D>
void advance_impl(It& it, D d, bidirectional_iterator_tag)
{
if (d > D(0)) { for (D i(0); i < d; ++i) { ++it; } }
else { for (D i(0); i > d; --i) { --it; } }
}
template <typename It, typename D>
void advance_impl(It& it, D d, input_iterator_tag)
{
for (D i(0); i < d; ++i) { ++it; }
}
Run Code Online (Sandbox Code Playgroud)
最后:
template <typename It, typename D>
void advance(It& it, D d)
{
typename std::iterator_traits<It>::iterator_category c;
advance_impl(it, d, c);
}
Run Code Online (Sandbox Code Playgroud)
为什么不在if
这种情况下只使用一个?因为它不会编译.
+=
--
因此,实现该功能的唯一方法是仅使用给定类型的可用操作静态地调度到函数.