构造函数,模板和非类型参数

天顶

我有一个必须由于某些原因而依赖int模板参数的类。
出于同样的原因,该参数不能成为该类的参数列表的一部分,而应成为其构造函数的参数列表的一部分(当然是模板化的)。

这里出现了问题。
也许我缺少了一些东西,但是我看不到向构造函数提供这样的参数的简便方法,因为无法推论或明确指定它。

到目前为止,我发现了以下替代方法:

  • 将上述参数放入类的参数列表中

  • 创建一个工厂方法或工厂函数,可以将其作为示例调用 factory<42>(params)

  • 构造函数提供特征结构

我试图为最后提到的解决方案创建一个(并非如此)最小的有效示例,也是为了更好地解释问题。
示例中的类本身不是模板类,关键点是构造函数,无论如何,真正的类是模板类。

#include<iostream>
#include<array>

template<int N>
struct traits {
    static constexpr int size = N;
};

class C final {
    struct B {
        virtual ~B() = default;
        virtual void foo() = 0;
    };

    template<int N>
    struct D: public B{
        void foo() {
            using namespace std;
            cout << N << endl;
        }

        std::array<int, N> arr;
    };

 public:
     template<typename T>
     explicit C(T) {
         b = new D<T::size>{};
     }

     ~C() { delete b; }

     void foo() { b->foo(); }

 private:
     B *b;
};

int main() {
    C c{traits<3>{}};
    c.foo();
}

老实说,上述解决方案都不适合:

  • 将参数移到类的参数列表中会完全破坏其设计,而不是可行的解决方案

  • 我想避免使用工厂方法,但是它可以解决问题

  • 到目前为止,特质结构似乎是最好的解决方案,但是我不完全满意

问题很简单:是否有我错过的东西,也许是更简单,更优雅的解决方案,我完全忘记的语言细节,还是上面提到的三种方法是我必须选择的方法?
任何建议,将不胜感激。

巴里

您必须传递一些可以推论的东西用最简单的事情仅仅是一个int一个空的包装:std::integral_constant因为int我相信您只想要s,所以我们可以为其加上别名,然后仅接受该特定类型:

template <int N>
using int_ = std::integral_constant<int, N>;

您的C构造函数只接受这一点:

 template <int N>
 explicit C(int_<N> ) {
     b = new D<N>{};
 }

 C c{int_<3>{}};

您甚至可以全力以赴,为此创建一个用户定义的文字(例如Boost.Hana),以便您可以编写:

auto c = 3_c; // does the above

另外,请考虑将特征直接转发到D如果到处都是类型,则元编程会更好地工作。也就是说,仍然在中接受相同int_的内容C

template <class T>
explicit C(T ) {
    b = new D<T>{};
}

现在哪里D期望有::value

template <class T>
struct D: public B{
    static constexpr int N = T::value;

    void foo() {
        using namespace std;
        cout << N << endl;
    }

    std::array<int, N> arr;
};

从用户C的角度来看,这两者都是相同的,但值得一提。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章