c++ - C++ 中的组模板参数

标签 c++ templates constexpr

我正在构建一个独立于维数的算法,其中维数是一个模板参数。我有许多输入和输出维度。

对于 5 个输入维度和 3 个输出维度,理想情况下,这看起来像这样:

my_algorithm<5, 3> algo;

但是,我经常需要输入和输出维度的总和。所以我想到的是:

template <size_t IDims, size_t ODims = 3, size_t Dims = IDims + ODims>
class my_algorithm;

这样一来,总维数也是一个编译时间常量。请注意,最常见的场景只有 3 个输出维度,因此我将其作为默认参数。这让我很高兴:

my_algorithm<5> algo;

但是,我没有这个很长的模板签名,我必须为这个类中的每个方法写下来。例如:

template <size_t IDims, size_t ODims, size_t Dims>
my_algorithm<IDims, ODims, Dims>::prepare(size_t k, size_t Kcap) {
    m_Kcap = Kcap;
    m_pi = new float[Kcap]{1.0f / k};
}

我真的不喜欢这样,想知道是否有一种优雅的方法可以将这些模板参数组合成某种结构。我想出了这样一个迷你测试:

#include <cstdio>

template<size_t IDims, size_t ODims = 3>
struct Dims {
    static constexpr size_t I = IDims;
    static constexpr size_t O = ODims;
    static constexpr size_t A = I + O;
};

template<typename D>
void function() {
    std::printf("function() with Dims<%zu, %zu, %zu>\n", D::I, D::O, D::A);
}

int main() {
    function<Dims<2, 4>>();
    function<Dims<2>>();
    return 0;
}

现在我只有一个要包含的参数 (typename D),但我不喜欢你如何真正地插入所有内容,而不仅仅是一个 Dims 结构。

最佳答案

我采用了问题中发布的方法。唯一烦人的是它需要 C++17,因为 Dims 结构的 constexpr static 成员并不总是内联。这有点奇怪。在某些情况下,它可以通过首先将其提取到本地 constexpr 来修复,如下所示:

template<typename D>
void my_algo<D>::some_function(size_t number) {
    constexpr DA = D::A;
    Eigen::Matrix<float, D::A, Eigen::Dynamic> vector (DA, number);
    //                   ^^^^                          ^^
    //                   works                 here D::A doesn't work
}

D::A 报告的错误是链接器无法找到该符号。 C++17 现在隐式内联这些 static constexpr,因此链接器不再需要它们,因为它们完全存在于对象文件本身中。

关于c++ - C++ 中的组模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48666005/

相关文章:

C#:我可以像在 C++ 中那样写 "private:"或 "protected:"区域吗

C++模板替换错误

c++ - C++ constexpr if 语句的灵活性

c++ - 在编译时评估函数成本的通用方法

c++ - constexpr 模板参数的显式指定参数无效

C++ 初始化列表和内存分配

c++ - 如何在Ubuntu上构建Shallot?

c++ - 从枚举中选择合适的函数

c++ - VS2015 的第一步,使用 C++。托管/非托管类错误。我做错了什么?

具有多个类型名的 C++ 模板