代码之家  ›  专栏  ›  技术社区  ›  meguli

基于整数常量比较的模板专门化

  •  2
  • meguli  · 技术社区  · 6 年前

    这是我有的东西:

    template <typename T, std::size_t dim>
    struct vector;
    
    template <std::size_t dim>
    struct vector<float, dim>
    {
        // I want this implementation for dim <= 4
    }
    
    template <std::size_t dim>
    struct vector<float, dim>
    {
        // I want this implementation for dim > 4
    }
    
    int main() {
        vector<float, 3> v1; // should instantiate first one
        vector<float, 7> v2; // should instantiate second one
    }
    

    现在,这当然不是一个有效的例子,因为我不能让它起作用。我不知道如何安排专门化模板签名。它们现在是相同的模板参数,不会编译。不知怎么的,一种sfinae应该会出现在图片中,但我不允许在部分专门化上使用默认模板参数。

    我可以用 constexpr if 以处理代码选择并使用一个专门化。但我相信,有独立的专业化这些使事情更可读和管理。

    你将如何实现这一目标?

    3 回复  |  直到 6 年前
        1
  •  6
  •   super    6 年前

    你可以通过使用sfinae来实现这一点。将额外的模板参数添加到未特殊化的模板,然后确保在特定条件下在专门化中与之匹配。

    template <typename T, std::size_t dim, typename = void>
    struct vector;
    
    template <std::size_t dim>
    struct vector<float, dim, std::enable_if_t<(dim <= 4)>>
    {
        // I want this implementation for dim <= 4
    };
    
    template <std::size_t dim>
    struct vector<float, dim, std::enable_if_t<(dim > 4)>>
    {
        // I want this implementation for dim > 4
    };
    
    int main() {
        vector<float, 3> v1; // should instantiate first one
        vector<float, 7> v2; // should instantiate second one
    }
    

    std::enable_if_t 将推断为 void 默认情况下,如果传递给它的条件为true。如果没有,它将不会推断出任何导致替换失败的结果,从而为任何其他模板匹配留下道路。

    STD:Enable 要求 c++14 但你可以用 typename std::enable_if<condition>::type 自从 c++11

        2
  •  3
  •   Dmytro Dadyka    6 年前

    使用附加层的可能解决方案。我们使用额外的 bool 此参数的模板参数和专门化。可用于低于++11的版本。

    template <typename T, std::size_t dim, bool moreThanFour>
    struct vectorImpl;
    
    template <std::size_t dim>
    struct vectorImpl<float, dim, false>
    {
       // I want this implementation for dim <= 4
    };
    
    template <std::size_t dim>
    struct vectorImpl<float, dim, true>
    {
       // I want this implementation for dim > 4
    };
    
    template <typename T, std::size_t dim>
    struct vector : public vectorImpl < T, dim, (dim > 4) > {};
    
    int main() {
       vector<float, 3> v1; // should instantiate first one
       vector<float, 7> v2; // should instantiate second one
    }
    
        3
  •  1
  •   tinkertime    6 年前

    通过概念,您可以简单地编写:

    template <typename T, std::size_t dim>
    struct vector;
    
    template <std::size_t dim>
        requires (dim <= 4)
    struct vector<float, dim>
    {
        // I want this implementation for dim <= 4
    };
    
    template <std::size_t dim>
        requires (dim > 4)
    struct vector<float, dim>
    {
        // I want this implementation for dim > 4
    };
    

    穿上它 godbolt

    我们只能等他们