英文:
C++ Set Template Bool Parameter from Class Constructor Argument
问题
下面是翻译好的部分:
我已经在下面尽量简化了场景。想象一个具有使用布尔参数的模板特化的类。
template <bool hasExtraParam>
class TestClass {};
template <>
class TestClass<true> {
public:
int param1;
int param2;
};
template <>
class TestClass<false> {
public:
int param1;
};
现在,我想要一个容器类,它作为成员变量持有大量这些 TestClass 实例。我希望能够基于构造函数参数设置每个成员变量的模板参数,如下所示:
constexpr bool ep1, ep2, ep3, ep4;
class Container {
public:
constexpr Container(bool extraParam1, bool extraParam2, bool extraParam3,
bool extraParam4) {
ep1 = extraParam1;
ep2 = extraParam2;
ep3 = extraParam3;
ep4 = extraParam4;
}
TestClass<ep1> testClass1;
TestClass<ep2> testClass2;
TestClass<ep3> testClass3;
TestClass<ep4> testClass4;
};
我该如何实现这种模式?我想在实际用例中传递一个大型配置结构体,其中包含一个布尔值,该值将链接到每个成员变量,设置其相应的模板参数。我无法理解如何实现这一点,感觉自己可能错过了解决问题的某种基本方法。此外,出于可扩展性考虑,我不认为容器应该有大量的模板参数,因为配置结构体可能很大。
希望这对你有帮助。如果你有其他问题或需要进一步的帮助,请随时告诉我。
英文:
I've simplified the scenario as much as possible below. Imagine a class that has template specialization using a bool parameter.
template <bool hasExtraParam>
class TestClass {};
template <>
class TestClass<true> {
public:
int param1;
int param2;
};
template <>
class TestClass<false> {
public:
int param1;
};
Now, I would like to have a container class that holds a large amount of these TestClasses as member variables. I want to be able to set the template parameter of each member variable based on the constructor arguments as below:
constexpr bool ep1, ep2, ep3, ep4;
class Container
{
public:
constexpr Container(bool extraParam1, bool extraParam2, bool extraParam3,
bool extraParam4)
{
ep1 = extraParam1;
ep2 = extraParam2;
ep3 = extraParam3;
ep4 = extraParam4;
}
TestClass<ep1> testClass1;
TestClass<ep2> testClass2;
TestClass<ep3> testClass3;
TestClass<ep4> testClass4;
};
How can I achieve this pattern? I want for my actual use-case to pass in a large config struct that has a boolean that will link to each member variable setting its respective template parameter. I cannot wrap my head around how to achieve this and feel like I'm missing some alternate fundamental approach to the problem. Also, I don't this its feasible for Container to have a bunch of templated arguments for scalability purposes since the config struct can be large.
答案1
得分: 1
你正在尝试的在C++中是不可能的。模板参数只能在编译时指定。相反,你将不得不在运行时动态实例化对象,例如:
class TestClassBase {
public:
virtual ~TestClassBase() = default;
// 两个类的共同成员...
// 供两个类覆盖的虚拟方法...
};
template <bool hasExtraParam>
class TestClass {};
template <>
class TestClass<true> : public TestClassBase {
public:
int param1;
int param2;
// 根据需要重写虚拟方法...
};
template <>
class TestClass<false> : public TestClassBase {
public:
int param1;
// 根据需要重写虚拟方法...
};
class Container
{
public:
Container(bool extraParam1, bool extraParam2, bool extraParam3, bool extraParam4)
{
testClass1 = extraParam1 ? new TestClass<true> : new TestClass<false>;
testClass2 = extraParam2 ? new TestClass<true> : new TestClass<false>;
testClass3 = extraParam3 ? new TestClass<true> : new TestClass<false>;
testClass4 = extraParam4 ? new TestClass<true> : new TestClass<false>;
}
~Container()
{
delete testClass1;
delete testClass2;
delete testClass3;
delete testClass4;
}
TestClassBase* testClass1;
TestClassBase* testClass2;
TestClassBase* testClass3;
TestClassBase* testClass4;
};
或者:
template <bool hasExtraParam>
class TestClass {};
template <>
class TestClass<true> {
public:
int param1;
int param2;
};
template <>
class TestClass<false> {
public:
int param1;
};
class Container
{
public:
Container(bool extraParam1, bool extraParam2, bool extraParam3, bool extraParam4)
{
if (extraParam1)
testClass1.emplace<TestClass<true>>();
else
testClass1.emplace<TestClass<false>>();
if (extraParam2)
testClass2.emplace<TestClass<true>>();
else
testClass2.emplace<TestClass<false>>();
if (extraParam3)
testClass3.emplace<TestClass<true>>();
else
testClass3.emplace<TestClass<false>>();
if (extraParam4)
testClass4.emplace<TestClass<true>>();
else
testClass4.emplace<TestClass<false>>();
}
std::variant<TestClass<true>, TestClass<false>> testClass1;
std::variant<TestClass<true>, TestClass<false>> testClass2;
std::variant<TestClass<true>, TestClass<false>> testClass3;
std::variant<TestClass<true>, TestClass<false>> testClass4;
};
英文:
What you are attempting is not possible in C++. Template aarguments can only be specified at compile-time. You will have to instantiate the objects dynamically at runtime instead, eg:
class TestClassBase {
public:
virtual ~TestClassBase() = default;
// common members of both classes...
// virtual methods for both classes to override...
};
template <bool hasExtraParam>
class TestClass {};
template <>
class TestClass<true> : public TestClassBase {
public:
int param1;
int param2;
// override virtual methods as needed...
};
template <>
class TestClass<false> : public TestClassBase {
public:
int param1;
// override virtual methods as needed...
};
class Container
{
public:
Container(bool extraParam1, bool extraParam2, bool extraParam3, bool extraParam4)
{
testClass1 = extraParam1 ? new TestClass<true> : new TestClass<false>;
testClass2 = extraParam2 ? new TestClass<true> : new TestClass<false>;
testClass3 = extraParam3 ? new TestClass<true> : new TestClass<false>;
testClass4 = extraParam4 ? new TestClass<true> : new TestClass<false>;
}
~Container()
{
delete testClass1;
delete testClass2;
delete testClass3;
delete testClass4;
}
TestClassBase* testClass1;
TestClassBase* testClass2;
TestClassBase* testClass3;
TestClassBase* testClass4;
};
Alternatively:
template <bool hasExtraParam>
class TestClass {};
template <>
class TestClass<true> {
public:
int param1;
int param2;
};
template <>
class TestClass<false> {
public:
int param1;
};
class Container
{
public:
Container(bool extraParam1, bool extraParam2, bool extraParam3, bool extraParam4)
{
if (extraParam1)
testClass1.emplace<TestClass<true>>();
else
testClass1.emplace<TestClass<false>>();
if (extraParam2)
testClass2.emplace<TestClass<true>>();
else
testClass2.emplace<TestClass<false>>();
if (extraParam3)
testClass3.emplace<TestClass<true>>();
else
testClass3.emplace<TestClass<false>>();
if (extraParam4)
testClass4.emplace<TestClass<true>>();
else
testClass4.emplace<TestClass<false>>();
}
std::variant<TestClass<true>, TestClass<false>> testClass1;
std::variant<TestClass<true>, TestClass<false>> testClass2;
std::variant<TestClass<true>, TestClass<false>> testClass3;
std::variant<TestClass<true>, TestClass<false>> testClass4;
};
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论