【问题标题】:Efficient way to convert a compile time known function argument to a std::integral_constant将编译时已知函数参数转换为 std::integral_constant 的有效方法
【发布时间】:2015-10-10 15:45:40
【问题描述】:

昨天我读到了blog entry 关于将编译时已知函数参数从 constexpr 函数转换为 std::integral_constant<> 之类的类型。

一个可能的用法示例是从用户定义的文字转换类型。

考虑以下示例:

constexpr auto convert(int i)
{
    return std::integral_constant<int, i>{};
}

void test()
{
    // should be std::integral_constant<int, 22>
    using type = decltype(convert(22));
}

但显然,正如预期的那样,Clang 会抛出以下错误:

error: ‘i’ is not a constant expression return std::integral_constant<int, i>{}; ^

上述博客的作者建议使用模板化的用户定义文字来拆分 将数字转换为 std::integer_sequence 以将其解析为 int。

但这个建议对我来说似乎没有用。

有没有一种有效的方法可以将编译时已知的函数参数转换为std::integral_constant&lt;&gt; 之类的类型?

【问题讨论】:

  • using type = decltype(convert(22)); 如何比别名模板(或变量模板)更具可读性?
  • 除了一厢情愿之外,您是否有任何理由怀疑您从该博客文章中获得的信息?它已经解释了为什么这是无效的,我看不出这里的答案告诉你同样的事情可以改进。
  • using type = decltype(convert(22)) 只是一个如何提取给定表达式类型的示例。我考虑了将表达式 convert(22) 解析为编译时 AST 表达式的可能性,该表达式可以在不使用宏或用户定义的文字的情况下从其他模板进行评估。

标签: c++ templates c++14


【解决方案1】:

函数参数可以永远是编译时常量。虽然在我看来这是constexpr 的设计缺陷,但它就是这样。

可能有其他方法可以做你想做的事(宏、模板),但你不能用函数参数来做。

【讨论】:

    【解决方案2】:

    您需要使用模板:

    template <int i>
    constexpr auto convert()
    {
        return std::integral_constant<int, i>();
    }
    
    void test()
    {
        // should be std::integral_constant<int, 22>
        using type = decltype(convert<22>());
    }
    

    或者(更好)你可以使用模板别名:

    template <int i> using convert = std::integral_constant<int, i>;
    void test()
    {
        // should be std::integral_constant<int, 22>
        using type = convert<22>;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-26
      相关资源
      最近更新 更多