【问题标题】:Max sizeof metafunction in variadic templates可变参数模板中元函数的最大大小
【发布时间】:2017-09-05 16:13:48
【问题描述】:

我正在尝试在可变参数模板中实现一个元函数(?),以在编译时计算几种类型的 sizeof 的最大值。

template<typename... Ts> struct MaxSizeof {
  static constexpr size_t value = 0;
};

template<typename T, typename... Ts> struct MaxSizeof {
  static constexpr size_t value = std::max(sizeof(T), typename MaxSizeof<Ts...>::value);
};

但我遇到了一些奇怪的错误:

MaxSizeof.h(7): error C3855: 'MaxSizeof': template parameter 'Ts' is incompatible with the declaration
MaxSizeof.h(7): error C2977: 'MaxSizeof': too many template arguments
MaxSizeof.h(5): note: see declaration of 'MaxSizeof'

您能帮我修改一下代码吗?

编译器为MSVC++2017工具集v141。

【问题讨论】:

  • 您在 constexpr 之前是否缺少 static
  • @Phil1970,谢谢,我已经更新了代码和错误消息。

标签: c++ c++11 templates metaprogramming variadic-templates


【解决方案1】:

你的专业没有正确的语法,应该是:

template<typename T, typename... Ts>
struct MaxSizeof<T, Ts...> { // Note the <T, Ts...> here
    // ....
};

【讨论】:

    【解决方案2】:

    std::max 自 C++14 起仅标记为 constexpr,因此您必须自己编写。此外,您不能重载结构,这也是您的代码失败的原因之一。

    这是一个需要 C++14 的 std::max 的解决方案,您可以根据需要更改为使用自定义的解决方案。

    template<typename... Ts>
    struct MaxSizeof : std::integral_constant<std::size_t, std::max({sizeof(Ts)...})> {};
    

    【讨论】:

    • 但是eli.thegreenplace.net/2014/variadic-templates-in-c 在“可变数据结构”下的第一个示例中,作者似乎重载了一个结构,不是吗?
    • @SergeRogatch 如果你的意思是第一个,那是一个函数。后面还有一个结构体,就是部分特化。
    【解决方案3】:

    需要修复 2 个问题:

    1. 正如@Phil1970 所指出的,我忘记了staticvalue 定义。
    2. 我必须在第 7 行指定模板参数:struct MaxSizeof&lt;T, Ts...&gt; { 而不是简单的 struct MaxSizeof {

    所以下面的代码编译:

    template<typename... Ts> struct MaxSizeof {
      static constexpr size_t value = 0;
    };
    
    template<typename T, typename... Ts> struct MaxSizeof<T, Ts...> {
      static constexpr size_t value = std::max(sizeof(T), typename MaxSizeof<Ts...>::value);
    };
    

    【讨论】:

      【解决方案4】:

      需要另一个小修复:

      template<typename T, typename... Ts> struct MaxSizeof<T, Ts...> {
        static constexpr size_t value = std::max(sizeof(T), MaxSizeof<Ts...>::value); // there should be with no `typename` 
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-18
        • 2016-07-15
        • 1970-01-01
        • 2021-10-01
        • 2021-11-26
        • 1970-01-01
        相关资源
        最近更新 更多