gpt4 book ai didi

c++ - 使用模板对单个 c++ 对象和 std::pair 对象进行抽象

转载 作者:太空狗 更新时间:2023-10-29 21:41:03 27 4
gpt4 key购买 nike

假设以下模板构造:

enum class ENUM {SINGLE, PAIR};
// General data type
template<ENUM T, class U>class Data;
// Partially specialized for single objects
template<class U>Data<ENUM::SINGLE, U> : public U {
// Forward Constructors, ...
};
// Partially specialized for pairs of objects
template<class U>Data<ENUM::PAIR, U> : public std::pair<U,U> {
// Forward Constructors, ...
};

在我的代码中,我希望能够编写类似的东西

template<ENUM T>someMethod(Data<T, SomeClass> data) {
for_single_or_pair {
/*
* Use data as if it would be of type SomeClass
*/
}
}

这应该与以下方法的组合相同:

template<>someMethod(Data<ENUM::SINGLE, SomeClass> data) {
data.doStuff();
}

template<>incrementData(Data<ENUM::PAIR, SomeClass> data) {
data.first.doStuff();
data.second.doStuff();
}

即我希望能够像使用单个对象一样使用一对对象(相同类型)。当然我可以重新实现一个类型的方法 T对于 Data<ENUM::PAIR, T> (请参阅 dau_sama 的回答)对于给定的示例,它看起来像:

template<>Data<ENUM::PAIR, SomeClass> : public std::pair<SomeClass, SomeClass> {
doStuff() {
this->first.doStuff();
this->second.doStuff();
}
};

但我必须对许多方法和运算符以及许多不同的类型执行此操作,尽管这些方法和运算符看起来都像这个示例。

解决方案的语法可能与我上面写的有很大不同,这只是为了演示我想要实现的目标。我更喜欢没有宏的解决方案,但也可以接受。

这样的抽象能否在C++11中实现?

我想这样做的原因是

  1. 我不必特化适用于 ENUM::Single 的模板化方法和 ENUM::PAIR当特化之间的所有差异都将对上述模式进行数学运算时(避免大量代码重复)。
  2. 相同的模式在我的代码中经常出现,我可以避免在许多地方实现变通办法,这些变通办法在每种情况下几乎都是相同的。

最佳答案

您可以尝试创建一个模板方法 applyMethod。这是一个完整的例子。我使用了一个只包含一个静态方法的 Executor 类,因为我找不到更好的方法来处理采用任何类型参数的方法

#include <iostream>
#include <string>

enum ENUM {SINGLE, PAIR};
// General data type
template<ENUM T, class U>class Data {
};
// Partially specialized for single objects
template<class U>
class UData : public Data<ENUM::SINGLE, U>, public U {
// Forward Constructors, ...
public:
UData(const U& u): U(u) {};
};
// Partially specialized for pairs of objects
template<class U>
class PData : public Data<ENUM::PAIR, U>, public std::pair<U,U> {
// Forward Constructors, ...
public:
PData(const U& u1, const U& u2): std::pair<U, U>(u1, u2) {};
};

template <class U, typename... P>
class Executor {
Executor() = delete;
public:
template<void (U::*M)(P... params)>
static void applyMethod(Data<ENUM::SINGLE, U> &data, P ...params) {
UData<U>& ud= reinterpret_cast<UData<U>& >(data);
U& u = static_cast<U&>(ud);
(u.*M)(params...);
}
template<void (U::*M)(P... params)>
static void applyMethod(Data<ENUM::PAIR, U> &data, P ...params) {
PData<U>& pd = reinterpret_cast<PData<U>& >(data);
(pd.first.*M)(params...);
(pd.second.*M)(params...);
}
};

class X {
std::string name;
public:
X(const std::string& name): name(name) { };

void doStuff(void) {
std::cout << "DoStuff : " << name << std::endl;
}
void doStuff(int i) {
std::cout << "DoStuff : " << name << " - " << i << std::endl;
}
};

int main() {
X x1("x1");
X x2("x2");
X x3("x3");

UData<X> data1(x1);
PData<X> data2(x2, x3);

Executor<X>::applyMethod<&X::doStuff>(data1);
Executor<X, int>::applyMethod<&X::doStuff>(data2, 12);

return 0;
}

关于c++ - 使用模板对单个 c++ 对象和 std::pair 对象进行抽象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29842729/

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