gpt4 book ai didi

c++ - 专门针对指向数据成员的指针的模板成员函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:38:27 25 4
gpt4 key购买 nike

我想定义一个 nullary 静态模板成员函数,它将(明确地)专门针对指向数据成员的指针,并且对于每个专门化,可以具有不同的返回类型。

它应该返回有关每个属性的一些详细信息,因此我将调用此方法 trait .返回的特征对象类型将由其他模板检查,因此整个机制必须在编译时可用。

到目前为止,我有这样的东西(当然是损坏的代码):

class Foo{
// some data members
int a; std::string b; int c;
// how to declare generic template here?
// compile-time error should ensue if none of the specializations below is matched

// specialization for a (aTraitExpr is expanded from macro, so it is OK to repeat it)
template auto trait<&Foo::a>()->decltype(aTraitExpr){ return aTraitExpr; }
// specialization for b; the return type will be different than for trait<&Foo::a>
template auto trait<&Foo::b>()->decltype(bTraitExpr){ return bTraitExpr; }
};

// some code which queries the trait at compile-time
// e.g. supposing all possible trait types declare isSerializable
// which happens to be True for a and False for b

Foo* foo;
template<bool isSerializable> void doSerialization(...);
template void doSerialization<true>(...){ ... };
template void doSerialization<false>(...){ /* no-op */ };

doSerialization<Foo::trait<&Foo::a>()::isSerializable>(...); // -> doSerialization<true>(foo)
doSerialization<Foo::trait<&Foo::b>()::isSerializable>(...); // -> doSerialization<False>(...)
doSerialization<Foo::trait<&Foo::c>()::isSerializable>(...); // -> compile error, specialization Foo::trait<&Foo::c> not defined

可以得到一些关于如何实现这一点的提示吗? (我并不是要发明一个新的序列化系统,我已经使用了 boost::serialization;每个特征中会有更多信息,这只是一个例子,为什么在编译时需要它)。

编辑: 我能够得到接近我想要的东西,显示为 at ideone.com .我放弃了 trait<Foo::a>() (现在),所以有静态函数 getTrait_a()它返回对可修改类型特征的引用,但是这些特征在编译时部分固定(例如 Foo::TraitType_a::flags 有效)。感谢所有回答的人,很遗憾我只能选择其中一个作为“答案”。

最佳答案

看起来您想要多个重载 而不是特化。不幸的是你没有详细说明什么 xTraitExpr是,但它似乎只是一个有成员 isSerializable 的类型定义。我可能会这样走

class Foo {
// your members have been omitted to save space...

template<typename T, T Foo::*M>
struct W { };

static decltype(aTraitExpr) trait(W<int, &Foo::a>) {
return aTraitExpr;
}

static decltype(bTraitExpr) trait(W<std::string, &Foo::b>) {
return bTraitExpr;
}

// other overloads for other members...

public:
// overloads for each member type
template<int Foo::*M>
static decltype(trait(W<int, M>())) trait() {
return trait(W<int, M>());
}

template<std::string Foo::*M>
static decltype(trait(W<std::string, M>())) trait() {
return trait(W<std::string, M>());
}
};

trait(W<M>())是依赖调用。依赖调用在定义和实例化时执行 ADL,仅在定义时执行非限定查找。这就是为什么 W和额外的 trait使用它的重载必须在 trait 之前定义类型重载而不是在它们之后,否则返回类型和函数主体的解析结果将不同,因为它们是在不同的时间解析的(主体在类定义之后延迟解析,返回类型立即解析)。

您可以制作 trait一个constexpr函数和制作xTraitExpr是一个带有 constexpr 构造函数初始化 isSerializable 的文字类适本地,或者你可以申请 decltype如下

doSerialization<decltype(Foo::trait<&Foo::a>())::isSerializable>(...);

关于c++ - 专门针对指向数据成员的指针的模板成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10570589/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com