gpt4 book ai didi

c++ - 根据抽象工厂中可用的重载版本自动选择构造函数

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

我正在使用 C++ 模板编写一个抽象工厂,但遇到了一个小障碍。即,泛型类 T 可以提供以下一种或多种构造对象的方法:

static T* T::create(int arg);
T(int arg);
T();

我正在编写抽象工厂类,以便它可以按给定顺序自动尝试这三种可能的构造:

template <class T>
class Factory {
public:
T* create(int arg) {
return T::create(arg); // first preference
return new T(arg); // this if above does not exist
return new T; // this if above does not exist
// compiler error if none of the three is provided by class T
}
};

如何使用 C++ 模板实现此目的?谢谢。

最佳答案

沿着这条线的东西应该工作:

struct S { static auto create(int) { return new S; } };
struct T { T(int) {} };
struct U {};

template<int N> struct tag: tag<N-1> {};
template<> struct tag<0> {};

class Factory {
template<typename C>
auto create(tag<2>, int N) -> decltype(C::create(N)) {
return C::create(N);
}

template<typename C>
auto create(tag<1>, int N) -> decltype(new C{N}) {
return new C{N};
}

template<typename C>
auto create(tag<0>, ...) {
return new C{};
}

public:
template<typename C>
auto create(int N) {
return create<C>(tag<2>{}, N);
}
};

int main() {
Factory factory;
factory.create<S>(0);
factory.create<T>(0);
factory.create<U>(0);
}

它基于 sfinae 和标签调度技术。
基本思想是将工厂的 create 函数转发给一组内部函数。由于 tag 的存在,这些函数会按顺序测试您要查找的功能,如果测试失败,这些函数将被丢弃。由于 sfinae,只要其中一个成功,代码就会编译并且一切都按预期工作。


这是 C++17 中的类似解决方案:

#include <type_traits>
#include <iostream>
#include <utility>

struct S { static auto create(int) { return new S; } };
struct T { T(int) {} };
struct U {};

template<typename C> constexpr auto has_create(int) -> decltype(C::create(std::declval<int>()), bool{}) { return true; }
template<typename C> constexpr auto has_create(char) { return false; }

struct Factory {
template<typename C>
auto create(int N) {
if constexpr(has_create<C>(0)) {
std::cout << "has create" << std::endl;
return C::create(N);
} else if constexpr(std::is_constructible_v<C, int>) {
std::cout << "has proper constructor" << std::endl;
return new C{N};
} else {
std::cout << "well, do it and shut up" << std::endl;
(void)N;
return C{};
}
}
};

int main() {
Factory factory;
factory.create<S>(0);
factory.create<T>(0);
factory.create<U>(0);
}

感谢@StoryTeller 和@Jarod42 在这个艰难的早晨提供的帮助。
wandbox 上查看并运行.

关于c++ - 根据抽象工厂中可用的重载版本自动选择构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46762642/

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