当前位置: 首页 > 知识库问答 >
问题:

如果模板为整数类型,则仅对某些模板规范启用函数

端木明贤
2023-03-14

我有一个Vector类,它有一个 的模板,例如。我可以为二维空间中的向量执行vector<2>,为四维空间执行vector<4>等等。如果dim==specific value,我想在类中添加一些方法,例如crossproductvector<3>执行x,y,z,wgetters为一个足够维的向量执行x,y,z,w。如果与维度不正确的向量一起使用,我希望得到一个编译错误。

我到处看了很多,其中一个我认为比较接近的东西是std::enable_if,但是,我不知道如何在我的特定情况下使用它(条件是dim==xdim>x)。

这是正确的方式,还是有一个完全不同的方式我应该做这件事?

顺便说一下,我使用的是C++17。

共有2个答案

申博厚
2023-03-14

我将实现泛型接口的方法并添加

static_assert(dim==3,“此方法仅对三维向量有效。”)

作为每个方法中的第一行。与std::enable_if方法相比,这将产生更清晰的编译器错误消息。

您还可以将constexpr if(dim==x)用于方法主体的其余部分,如果需要不同的实现,则可以基于当前维度“专门化”代码。

司空海荣
2023-03-14

>

  • C++20之前,static_assert可能是最简单的:

    template <std::size_t Dims>
    struct Vector
    {
        // ...
        double getZ() const { static_assert(Dims >= 3);  return data[2]; }
    };
    

    SFINAE是可能的,但复杂而冗长:

    template <std::size_t Dims>
    struct Vector
    {
        // ...
        template <std::size_t D = Dims, std::enable_if_t<(D >= 3) && D == Dims, int> = 0>
        double getZ() const { return data[2]; }
    };
    

    专门化是可能的,但可能很棘手,例如:

    struct NullVector3{};
    
    template <typename Derived>
    struct Vector3
    {
        // ...
        double getZ() const { return static_cast<Derived*>(this)->data[2]; }
    };
    
    template <std::size_t Dims>
    struct Vector : std::conditional_t<(Dims >= 3), Vector3<Vector>, NullVector3> /*, ..*/
    {
        // ...
        // inherit of Vector3<Vector>::getZ() when Dims >= 3
        // inherit of no extra method from NullVector3 else.
    };
    

    C++20是最简单的要求:

    template <std::size_t Dims>
    struct Vector
    {
        // ...
        double getZ() const requires(Dims >= 3) { return data[2]; }
    };
    

  •  类似资料:
    • 使用以下代码生成时 生成以下诊断(代码后): 诊断: 有趣的部分不是关于歧义错误本身(这不是这里主要关注的问题)。有趣的是,当仅使用函数名调用fun时,第一个fun的模板参数F被解析为纯函数类型double(double),而第二个fun的模板参数F被解析为更期望的函数指针类型。 然而,当我们将调用<代码>乐趣(测试) 更改为<代码>乐趣( 这种行为似乎是所有Clang和GCC(以及Visual

    • 我想问,有没有可能限制我的模板函数,使它只接受我指定的几种类型?这就是如何告诉编译器在我使用cout< 更明确地说,这就是我要做的:

    • 我正在学习一个视频教程,我想声明一个模板函数作为模板类的朋友。我不知道为什么代码会抛出错误。 编译器抛出错误。 错误: templates\u friends\u 38。cpp:在“void doSomething2(T)[T=int]”的实例化中:templates\u friends\u 38。cpp:40:19:此处需要templates\u friends\u 38。cpp:32:9:错误

    • 在C++11之前,类模板和函数模板只能含有固定数量的模板参数。C++11增强了模板功能,允许模板定义中包含0到任意个模板参数,这就是可变参数模板。可变参数模板的加入使得C++11的功能变得更加强大,而由此也带来了许多神奇的用法。 可变参数模板 可变参数模板和普通模板的语义是一样的,只是写法上稍有区别,声明可变参数模板时需要在typename或class后面带上省略号...: template<ty

    • 我想知道如果函数的模板参数包括但不限于类的模板参数,如何使函数成为类的朋友并在类外定义函数。 例如,我有以下模板类和模板朋友函数: 如果我编译: 我会得到以下链接器错误:

    • 我有一个模板化的C++类,它也有一个模板化的成员函数。这个成员函数的模板参数以特定的方式依赖于类的模板参数(请参阅下面的代码)。我正在为其模板参数的两个不同值实例化(而不是专门化)该类。一切都在这一点上进行。但是,如果我调用模板化的成员函数,对第一个实例化对象的调用只会编译,而不会编译第二个。似乎编译器没有为模板类的第二次实例化实例化模板化成员函数。我正在使用“g++filename.cpp”编译