【问题标题】:Use templated struct as template parameter to static constexpr member使用模板结构作为静态 constexpr 成员的模板参数
【发布时间】:2017-12-18 20:27:07
【问题描述】:

我正在尝试设置模板结构的static constexpr 成员以由模板参数分配,该模板参数本身就是一个模板结构。例如:

template<int f>
struct Column
{
    static constexpr int flags = f;
};

template<Column<int> c> // Error: Template argument for non-type template parameter must be an expression
struct Row
{
    static constexpr Column<int> column = c; // Error: Template argument for non-type template parameter must be an expression
};

这用于创建其他带有信息的结构,例如:

struct Table
{
    static constexpr Column<5> myCol();
    static constexpr Row<myCol> myRow(); // Error: Value of type 'Column<5> ()' is not implicitly convertible to 'int'
};

Xcode 给出了 cmets 中描述的错误。我认为我想要实现的想法应该很清楚,但是我怎样才能正确地实现它呢?我希望Column&lt;int&gt; 的模板参数是通用的(例如,不使用Column&lt;5&gt;),以便Column&lt;int&gt; 的任何生成实例都可以用作Row 的模板参数。

编辑:更多上下文以更好地处理 XY 问题:

我正在创建代表 SQLite 列的模板化结构。这些模板结构将具有列名、标志、默认值等。这就是上面的Foo 类,用非常简单的话来说。

然后我将为 SQLite 行创建类似的结构。这些结构需要知道它们属于哪个列才能知道它有哪些标志(NOT NULLPRIMARY KEY 和类似的东西),如果有的话,它有哪些默认值,等等。因此,我想将列结构(即Foo&lt;int&gt;)作为模板参数传递给行结构(上例中的Bar)。

【问题讨论】:

  • 传递 foo 和整数,然后在 bar 中实例化 foo?看起来也像 XY 问题。
  • 应该Bar 只能与Foo 一起使用吗?
  • 是的,Bar 只能由Foo 实例化,但是 Foo 可能会获得比示例中更多的模板参数,尽管这无关紧要。
  • @Incomputable 你能告诉我如何做你的建议吗?还要感谢您对 XY 问题的评论——我以前没有听说过。有趣的“谬误”。有兴趣者:meta.stackexchange.com/questions/66377/what-is-the-xy-problem
  • @Krøllebølle,我确信现在它会解决问题,尽管不是最好的方式。

标签: c++ templates


【解决方案1】:

std::integral_constant

让我们看一个例子:

template <std::size_t index>
class column: public std::integral_constant<std::size_t, index>
{
    ...
};

然后,当传递到行时,反之亦然,使用这个:

template <std::size_t column_index>
class row 
{
    ...
};

现在,让我们使用它:

row<column<1>{}> myrow;

注意{},它将创建column 的实例,但它会自动衰减为std::size_t


问题是人们仍然可以直接将它与索引一起使用,因此您可能需要为此在代码库中进行一次clang-tidy 检查。


模板元编程

也可以使用部分特化。

template <typename column_t>
class row;

template <std::size_t column_index>
class row<column<column_index>>
{
    ...
}

【讨论】:

  • 这是您要搜索的内容吗?
【解决方案2】:

我想你想要类似的东西

template<int f>
struct Column
{
    static constexpr int flags = f;
};

template<int i>
struct Row
{
    static constexpr Column<i> col;
};

Column&lt;int&gt; 是一个无意义的类型,因为它将int 传递给一个模板,该模板期望int 类型的值作为其参数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-03
    • 2020-08-26
    • 2016-01-25
    • 1970-01-01
    • 1970-01-01
    • 2017-01-15
    相关资源
    最近更新 更多