- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我可以使用什么来使函数接受 N 个参数,其中 N 在编程时未知但在编译时固定(实际上是模板参数)?
所讨论的函数是一个位于性能关键路径中的访问函数,因此我正在寻找尽可能少的开销。
首先想到的是 std::initializer_list
,尽管有人告诉我它很便宜,但它仍然是一个不需要创建和复制的对象。更重要的是,它有一种时髦的方式来访问它的元素 initializer_list::begin[i]
(这是另一个我不关心的对象)并且不会将参数的数量严格限制为 N ,但这是一个小问题。
其次是模板参数包。那些可以成为可行的候选人吗?我将不得不使用递归来访问 N 个值。
我试图在此伪代码中展示的目标:
template<int dim, class T> class linear_searchspace {
template<T...args> operator() (args) {
return std::tie(some_kinda_structure[args[0]], some_kinda_structure[args[1]], some_kinda_structure[args[3]]);
}
};
我怎么能把它变成实际可行的递归形式呢?
澄清 args
应该是坐标。每个坐标是一个值在维度中的索引。因此传递了 N 个坐标,将返回 N 个值。这就像同时访问 N 个 vector 。我想为每个参数添加一个偏移量,这取决于参数的索引,因为它存储了一个数组,其中偏移量的索引对应于参数的索引。计算将是简单的算术。
什么是合适的返回类型?这将访问的结构很可能包含数值,最多是元组。 std::tuple
是我能做的最好的,还是有可能制作出性能更高的东西?
关于参数,任何东西都可以,甚至是宏。我很高兴听到这些年来你想出了什么把戏。
最佳答案
template <std::size_t DIM, typename T>
class linear_searchspace
{
public:
template <typename... Args>
inline constexpr auto operator()(Args... args) const
noexcept(noexcept(T{std::declval<T>()}))
-> std::tuple<decltype((void)args, T{std::declval<T>()})...>
{
static_assert(sizeof...(Args) == DIM, "wrong number of indices!");
using Tuple = std::tuple<decltype((void)args, T{std::declval<T>()})...>;
return get<Tuple>(make_index_sequence<sizeof...(Args)>{}, args...);
}
private:
template <typename Tuple, typename... Args, std::size_t... Is>
inline constexpr Tuple get(index_sequence<Is...>, Args... args) const
noexcept(noexcept(T{std::declval<T>()}))
{
return Tuple((some_kinda_structure[args] + Is)...);
// ^^^^
// some calculation for each element based on index (here simple addition)
}
T some_kinda_structure[DIM]; // implementation defined
};
(index_sequence
的实现在demo中)
通过上述解决方案,可以通过 constexpr
对象获得最高性能,因为整个操作是在编译时评估的:
int main()
{
constexpr linear_searchspace<5, int> lsp{};
// evaluated at compile-time
constexpr auto t = lsp(0, 1, 2, 3, 4);
static_assert(std::get<1>(t) == 1, "!");
// evaluated at run-time
auto t2 = lsp(4, 3, 2, 1, 0);
assert(std::get<3>(t2) == 3);
}
关于c++ - 采用 N 个参数并返回 N 个值的高性能解决方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26451409/
考虑以下代码: template struct list { template list(Args...) { static_assert(sizeof..
考虑以下代码: template struct list { template list(Args...) { static_assert(sizeof..
最近才开始学习"new"OpenGL(可编程而不是固定功能,我从 Nehe 教程中学到的),我想知道自从 OpenGL 4 发布以来学习 OpenGL 3 是否真的有用。 我问的原因是因为我想知道能够
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我想了解如何操作特征向量/矩阵。我想实现最小二乘高斯牛顿算法(因此我学习使用 Eigen 库)。我有一个 1x6 的参数 vector ,每次迭代都需要更新它们。现在,我只想弄清楚函数如何将 vect
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 5 年前。 Improv
我发现编写适用于Enums的静态方法非常困难。这是一个非常人为的示例,但假设您想要编写一个方法,该方法采用 Enum 常量并返回下一个声明的常量。我发现(大约一个小时后)你可以按如下方式进行。它可以工
我正在尝试编写一个函数,在某些条件下,将指向结构的指针更改为指向不同的结构。 我的限制是我想保留初始函数签名,该签名将指向指针(而不是特定结构类型)的通用指针作为参数。 这行不通: [nav] In
我正在尝试将 Keras 示例改编为 VAE https://blog.keras.io/building-autoencoders-in-keras.html 我修改了代码,使用有噪声的 mnist
自 JPA 2.0 以来,关系上有 orphanRemoval 属性,它极大地简化了父子关系的更新,并且与级联删除一起允许删除树的整个分支并轻松删除它。 但是,也有一些情况可能被标记为“收养”,即您将
我正在尝试编写一个类,它能够在以后及时调用不带参数的 lambda。我期待 C++17 类模板参数推导以避免需要工厂函数。但是,尝试在不指定类型的情况下实例化对象会失败。我可以很好地使用工厂功能,但我
我怎样才能避免并非所有控制路径都在此处返回容器的事实: enum Type {Int, String}; Container containerFactory(Type
我开始学习 C++ 和 STL。 我有一个问题: 写一个函数模板palindrome,接受一个 vector 参数并返回true或false来检查 vector 是否是回文(12321是回文,1234
我一直在尝试获取一个条目值(代码中的 S1)以将其自身设置为一个值(_attributes 字典中的 STR),但我就是无法让它工作。我想让它成为一个最终的顶层循环,但我在这方面一步一步来,因为我是一
我想做同样的事情 How do I get the number of days between two dates in JavaScript? 但我想对此日期格式执行相同操作:2000-12-31
我想编写一个带有构造函数的 C++ 类,该构造函数将 auto_ptr 作为其参数,以便我可以将类实例从 auto_ptr 初始化为另一个实例: #include class A { public:
我需要一种方法,我可以在其中获取二维数组中的输入并以最快的方式之一对其进行逐行排序。我尝试使用 Insertion Sort 同时获取 Input 和 Sort it。我使用的第二件事是我单独为一行取
好的,我已经阅读了一些关于 IDisposable 最佳实践的文章,我想我基本上明白了(终于)。 我的问题与从 IDisposable 基类继承有关。我看到的所有示例都在子类中一遍又一遍地编写相同的代
定义类时,以下是否有效? T(const T&&) = default; 我正在阅读移动构造函数 here并且它解释了如何仍然可以隐式声明默认值: A class can have multiple
我想使用 LoadLibrary 开发一个插件系统。 我的问题是:我希望我的函数采用 const char* 而 LoadLibrary 采用 LPCTSTR。 我有一个聪明的想法来做(LPCSTR)
我是一名优秀的程序员,十分优秀!