构造函数,模板和非类型参数 [英] Constructors, templates and non-type parameters

查看:108
本文介绍了构造函数,模板和非类型参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个必须出于某些原因而依赖于 int 模板参数的类。

由于相同的原因,该参数不能成为一部分该类的参数列表的一部分,它是其构造函数的参数列表的一部分(当然是模板化的)。

I've a class that must depend for some reasons from an int template parameter.
For the same reasons, that parameter cannot be part of the parameter list for the class, instead it is part of the parameter list of its constructor (that is, of course, templated).

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

Here the problems arose.
Maybe I'm missing something, but I can't see an easy way to provide such a parameter to the constructor, because it cannot be deduced nor explicitly specified.

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

So far, I've found the following alternatives:


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

  • put the above mentioned parameter into the parameter list of the class

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

create a factory method or a factory function which can be invoked as an example as factory<42>(params)

向构造函数提供 traits 结构

我尝试为最后提到的解决方案创建一个(不是这样)最小的有效示例

示例中的类本身不是模板类,关键是构造函数,反之,真正的类是模板类。


I tried to create a (not so) minimal, working example for the last mentioned solution, also in order to explain better the problem.
The class in the example is not a template class for itself, for the key point is the constructor, anyway the real one is a template class.

#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();
}

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

To be honest, none of the solutions above mentioned fits well:


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

  • moving the parameter into the parameter list of the class breaks completely its design and is not a viable solution

工厂方法是我要避免的方法,但它可以解决问题

a factory method is something I'd like to avoid, but it could solve the issue

特质结构似乎成为迄今为止最好的解决方案,但不知何故我不完全满意

the traits struct seems to be the best solution so far, but somehow I'm not completely satisfied

问题很简单:是
有什么我想念的东西,也许是更简单,更优雅的解决方案,我完全忘记的语言细节,还是上面提到的三种方法可供我选择?

The question is pretty easy: is there something I missed out there, maybe an easier, more elegant solution, a detail of the language I completely forgot, or are the three approaches mentioned above the ones from which I must choice?
Any suggestion would be appreciated.

推荐答案

您必须传递可以推断出的某些东西。使用最简单的方法是将一个int封装为空: std :: integral_constant 。因为我相信您只希望 int s,所以我们可以对其进行别名,然后仅接受该特定类型:

You have to pass in something that can be deduced. The simplest thing to use is just a empty wrapper for an int: std::integral_constant. Since you only want ints I believe, we can alias it and then only accept that specific type:

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

您的 C 构造函数只接受以下内容:

Where your C constructor just accepts that:

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

 C c{int_<3>{}};

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

You could even go all out and create a user-defined literal for this (a la Boost.Hana) so that you can write:

auto c = 3_c; // does the above






将特征转发到 D 。如果到处都是类型,则元编程会更好地工作。也就是说,仍然在 C 中接受相同的 int _


Also, consider simply forwarding the trait through to D. Metaprogramming works better if everything everywhere is a type. That is, still accept the same int_ in 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 的观点,但值得一想。

It's the same thing either way from the user of C's perspective, but just worth a thought.

这篇关于构造函数,模板和非类型参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆