c++ - 结构中的类型注入(inject)

标签 c++ templates traits template-meta-programming constexpr

我想我问的是不可能的,但我想完全确定,所以我还是问了..

我想从模板化结构(可在 constexpr 函数中使用)获取编译时值,该结构未在模板中传递,但以其他方式注入(inject)。

这很难解释,我会尝试一些代码:

template<int A>
struct MagicStruct
{
enum { current = A, injected = /* magic */}
};

template<int A, int B>
struct InjectionStruct
{
enum { first=A, second=B}
/*... injection of B in MagicStruct<A> ... */
};

static const int AVALUE = 1;
static const int BVALUE = 2;

static const int CVALUE = InjectionStruct<AVALUE, BVALUE>::first; //== 1
static const int CVALUE = InjectionStruct<AVALUE, BVALUE>::second; //== 2
static const int DVALUE = MagicStruct<AVALUE>::injection; //== 2

是否有一些我不知道的技巧可以做到这一点?

[edit] 我想在输入中使用 AVALUE 作为模板参数来获取 DVALUE

最佳答案

你可以制作injected进入static int相反:

template<int A>
struct MagicStruct
{
    enum { current = A };
    static int injected;
};

template<int A>
int MagicStruct<A>::injected;

然后给出InjectionStruct一个静态成员,其实例化将填充 MagicStruct<A>::injected :

template<int A, int B>
struct InjectionStruct : MagicStruct<A>
{
    enum { first=A, second=B};

    struct filler {
        filler() { MagicStruct<A>::injected = B; }
    };

    static filler inject;
};

template <int A, int B>
typename InjectionStruct<A,B>::filler InjectionStruct<A,B>::inject;

然后执行注入(inject),你只需要使用inject某处,或显式实例化它:

static const int AVALUE = 1;
static const int BVALUE = 2;

static const int CVALUE = InjectionStruct<AVALUE, BVALUE>::first; //== 1
static const int DVALUE = InjectionStruct<AVALUE, BVALUE>::second; //== 2
//explicit instantiation
template InjectionStruct<AVALUE,BVALUE>::filler
         InjectionStruct<AVALUE,BVALUE>::inject;
static const int EVALUE = MagicStruct<AVALUE>::injected; //== 2

或者,您可以隐藏 injected 的实例化在您用来检索 first 的某些函数中或 second .


这是一个疯狂的实现,它依赖于通过模板实例化注入(inject)函数的实现。如果它没有正确实现相关的标准规则,这可能不适用于您的编译器,但它仍然很有趣,并且在编译时完全透明地工作:

template<typename>struct Type{};

template<int A>
struct MagicStruct
{
    friend constexpr int get_injected(Type<MagicStruct<A>>);
    static constexpr int current() { return A; }

    template <int V = get_injected(Type<MagicStruct<A>>{})> 
    static constexpr int injected() { return V; } 
};


template<int A, int B>
struct InjectionStruct
{
    static constexpr int first() { return A; }
    static constexpr int second() { return B; }

    friend constexpr int get_injected(Type<MagicStruct<A>>) { return B; }
};

您对此实现的使用几乎完全符合您的要求:

static const int AVALUE = 1;
static const int BVALUE = 2;

static const int CVALUE = InjectionStruct<AVALUE, BVALUE>::first(); //== 1
static const int DVALUE = InjectionStruct<AVALUE, BVALUE>::second(); //== 2
static const int EVALUE = MagicStruct<AVALUE>::injected(); //== 2

Live demo

关于c++ - 结构中的类型注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42852924/

相关文章:

php - 级联更新列关系 Laravel 5.6

C++ header 保持理智

c++ - 没有抽象方法的抽象类

c++ - 如何使用 C++ 制作双重排序整数数组?

c++ - 如何在安装驱动程序之前用 C++ 获取 GPU 信息

c++ - 没有匹配的函数用于调用c++

scala - 何时在 Scala 特征中使用 val 或 def?

C++:创建一个模板函数,只允许继承特定接口(interface)的类?

c++ - 从父类(super class)函数返回子类定义

c++ - 有没有办法使用特征使 pos_type 和 off_type 成为 int64_t?