gpt4 book ai didi

c++ - 如何在模板函数中根据类型构造不同的对象?

转载 作者:行者123 更新时间:2023-12-02 21:04:51 25 4
gpt4 key购买 nike

这是我的问题,我有一个基类Base,两个派生类ClassAClassB形成Base > 仅采用两个参数,以及从采用三个参数的 ClassB 派生的两个类 ClassB0ClassB1。我想根据传递给函数create的类型创建类实例,如果该类型派生自ClassB,则第一个参数将填充10。编译器总是警告没有匹配的构造函数。

#include <iostream>
#include <type_traits>

class Base {};
class ClassA : public Base {
public:
ClassA(int a, int b) : Base() {
std::cout << "ClassA: " << a << " " << b << "\n\n";
}
};

class ClassB : public Base {
public:
ClassB(int a, int b, int c) : Base() {
std::cout << "ClassB: " << a << " " << b << " " << c << "\n";
}
};

class ClassB0 : public ClassB {
public:
ClassB0(int a, int b, int c) : ClassB(a, b, c) {
std::cout << "ClassB0: " << a << " " << b << " " << c << "\n\n";
}
};
class ClassB1 : public ClassB {
public:
ClassB1(int a, int b, int c) : ClassB(a, b, c) {
std::cout << "ClassB1: " << a << " " << b << " " << c << "\n\n";
}
};

template <typename T, typename ...Args>
T* create(Args&&... args) {
T* comp = nullptr;

if (std::is_base_of<ClassB, T>::value) {
std::cout << "True ";
comp = new T(10, std::forward<Args>(args)...);
} else {
std::cout << "False ";
comp = new T(std::forward<Args>(args)...);
}

return comp;
}

int main() {
create<ClassA>(1, 2);
create<ClassB0>(2, 3);
create<ClassB1>(2, 3);
}

最佳答案

问题是 ifelse 的分支都需要在编译时求值,尽管其中一个分支会在运行时求值。

您可以申请constexpr if statement (C++17 起),必须在编译时知道条件,并且 ifelse 分支将被丢弃并且不会被求值再次编译时。

If the value is true, then statement-false is discarded (if present), otherwise, statement-true is discarded.

template <typename T, typename ...Args>
T* create(Args&&... args) {
T* comp = nullptr;

if constexpr (std::is_base_of<ClassB, T>::value) {
// ^^^^^^^^^
std::cout << "True ";
comp = new T(10, std::forward<Args>(args)...);
} else {
std::cout << "False ";
comp = new T(std::forward<Args>(args)...);
}

return comp;
}

LIVE

在 C++17 之前,您可以使用 SFINAE 应用重载。 。例如

template <typename T, typename ...Args>
typename std::enable_if<std::is_base_of<ClassB, T>::value, T*>::type
create(Args&&... args) {
T* comp = nullptr;
std::cout << "True ";
comp = new T(10, std::forward<Args>(args)...);
return comp;
}
template <typename T, typename ...Args>
typename std::enable_if<!std::is_base_of<ClassB, T>::value, T*>::type
create(Args&&... args) {
T* comp = nullptr;
std::cout << "False ";
comp = new T(std::forward<Args>(args)...);
return comp;
}

LIVE

关于c++ - 如何在模板函数中根据类型构造不同的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59462808/

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