C++模板元编程,"static if"解决方法 - 可以改进吗?
C++ template metaprogramming, "static if" workaround - can it be improved?
我有一个函数,它扫描用户的文件系统,用路径填充向量,然后对其进行排序或不排序。由于用户应该能够在编译时决定是否要对向量进行排序,因此我使用模板和helper类来代替非常需要的(但不存在的)"静态"。
考虑以下代码:
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);
}
};
我上面写的代码比原始代码大大简化了,它接受多个模板参数,允许用户在编译时进一步定制函数的结果。
是否有替代使用所有这些助手类的方法?它真的很乱,很难阅读。
理想情况下,这是我想写的:
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)); }
}
};
由于您的值在编译时是已知的(非模板类型参数),您可以完美地编写"正常" if
:
template<Sort TS>
void someFunction(vector<string>& mTarget)
{
if (TS == Sort::Alphabetic) { sort(begin(mTarget), end(mTarget)); }
// else if (TS == Sort::Unsorted) {}
}
编译器将执行常量折叠和死代码消除(当然,如果启用了这些优化),结果将与使用假设的static_if
完全相同。
恐怕对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; }
}
最后:
template <typename It, typename D>
void advance(It& it, D d)
{
typename std::iterator_traits<It>::iterator_category c;
advance_impl(it, d, c);
}
在这种情况下为什么不使用if
呢?因为它无法编译。
- 双向迭代器不支持
+=
输入迭代器(或前向迭代器)不支持
--
因此,实现该功能的惟一方法是静态地只使用给定类型上的可用操作分派给函数。
模板专门化呢?
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
enum class Sort {
Alphabetic,
Unsorted
};
template<Sort TS> struct DoSomethingHelper {
static void someFunction(vector<string>& mTarget)
{}
};
template<> struct DoSomethingHelper<Sort::Unsorted> {
static void someFunction(vector<string>& mTarget) {
}
};
template<> struct DoSomethingHelper<Sort::Alphabetic> {
static void someFunction(vector<string>& mTarget) {
sort(begin(mTarget), end(mTarget));
}
};
int main() {
vector<string> v = {{"foo", "bar", "foo2", "superman", ".."}};
DoSomethingHelper<Sort::Alphabetic> helper;
helper.someFunction(v);
for (string& s : v) {
cout << s << endl;
}
return 0;
}
编辑:我是一个白痴。
相关文章:
- 在 if 语句中处理多个 or 的更优雅的方法是什么
- MSVC使用constexpr-if从可变模板方法中的基本模板参数中吞下const
- 多个 if-else 测试的更简单方法
- 有没有更有效的方法来替换这些多个 IF 语句?
- 在创建完整对象之前编写 if-can-add check 方法的正确方法?
- 一种无需使用if语句而无需使用阈值的方法
- 减少 if-elseif 语句的聪明方法
- 用 c++ 编写一堆类似的 if 语句的漂亮方法
- 有没有更简单的方法可以做到:if(num1 > num2 && num1 > num3),以获得更大的变量列表进行比较?
- 有没有简单的方法可以在 if-else 链的末尾做与 else 相反的事情
- 具有"else if"方法问题 C++ 的基本计算器
- 将字符串中的特定单词与c 中的if或while进行比较的最佳方法
- 适当使用IF Goto循环的方法
- 通过找到一种删除许多 if 语句的方法来简化代码
- C++对方法和What-if所有东西都转到.h的未定义引用
- 将字符串存储在要在 IF 语句中使用的数组中的可能方法
- 不使用 if 插入/更新 std::unordered_map 元素的最快方法是什么
- 编写 if then else 类型语句的简洁方法
- 用c++编写if-then-else语句的更有效方法
- 有更整洁的方法吗?C++IF