是否可以根据模板参数的值有条件地编译函数中的语句?例如:
localStorage
catch是基于chk的值我甚至不希望将语句template<typename T, bool chk>
class subject
{
public:
// the ideal case
void doSomething(T new_val)
{
if(chk)
{
if(new_val != val)
//do_something only if new_val is different from val
}
else
{
//do_something even if new_val and val are equal
}
}
//or if that's not possible, if chk = 0 use this method
void doSomething(T new_val)
{
//do_something even if new_val and val are equal
}
// and if chk = 1 use this method
void doSomething(T new_val)
{
if(new_val != val)
//do_something only if new_val is different from val
}
T val;
};
编译到函数中(因为那时使用的每个类型T都必须定义一个!=运算符)。
我想这种方法的一个缺点是if(new_val!=val)
和foo<int,0>
是不同的类,所以不可能定义一个不关心chk是0还是1的函数(比如说foo<int,1>
)。
我正在特别关注的应用程序是一个观察者,对于某些类型我只希望观察者在值实际发生变化时得到通知,对于其他类型我希望观察者始终得到通知(对于那些类型我不喜欢我不想要定义一个!=运算符。
这可能没有两个单独的课程吗?
答案 0 :(得分:2)
这可能没有两个单独的课程吗?
是的,确实如此。如果您不想专门化您的课程,以避免代码重复,您可以使用类似以下示例中的表达式:
#include <type_traits>
#include <iostream>
template<typename T, bool chk>
struct subject {
template<bool trigger = chk>
std::enable_if_t<trigger>
doSomething(T new_val) {
if(new_val != val) {
std::cout << "new_val != val" << std::endl;
} else {
std::cout << "new_val == val" << std::endl;
}
}
template<bool trigger = chk>
std::enable_if_t<not trigger>
doSomething(T new_val) {
std::cout << "who cares?" << std::endl;
}
T val;
};
int main() {
subject<int, true> s1{0};
s1.doSomething(0);
s1.doSomething(1);
subject<int, false> s2{0};
s2.doSomething(0);
s2.doSomething(1);
}
我们的想法是doSomething
的正确定义在编译时被选中,它取决于模板参数chk
的值。另一个定义按预期被简单地丢弃,并且根本不可用
请注意,要使sfinae表达式起作用,trigger
模板参数必须是成员函数模板的实际参数。这就是为什么你必须这样定义的原因:
template<bool trigger = chk>
sfinae_expression_based_on_enable_if
doSomething(T new_val) { /* ... */ }
在coliru上运行时看到它。
答案 1 :(得分:0)
您正在寻找的是模板专业化&#39;。
您必须专门化您的模板。定义基本模板后,如上所述,您将继续并定义其专业化:
template<typename T>
class subject<T, true>
{
public:
// ...
然后继续从头开始定义整个subject
类,进行所需的任何更改,对于第二个模板参数为true
(或false
的情况,如果是&# 39;你需要专业的东西)。您可以删除内容,添加内容或完全更改内容。专业类可以有不同的类成员,方法或相同的类方法,但它们的工作方式完全不同。
重要的是要了解您现在正在定义整个类,而不仅仅是不同的位。如果该类只有一个次要方面确实需要专门化,那么当然会产生一堆重复的代码;所以通常需要重构它,将变化的位放入辅助类或函数中,并专门处理变化的位。
即将推出的C ++ 17标准还有其他一些模板专业化的替代方案;但是,对于这些情况,专业化传统上是人们学习的第一件事。因此,你应该打开你的C ++书籍到讨论模板专业化的章节,并在开始使用C ++ 17中的新东西之前先获得好处。