如何将模板mixin作为参数
How to take template mixin as argument?
考虑一个c++模板mixin结构,我如何编写一个带有特定组件的mixin的函数?在本例中,如何将withAandB
赋给worksWithA()
?
struct Base {};
template <class T>
struct HasA : T
{
int A;
};
template <class T>
struct HasB : T
{
int B;
};
void WorksWithA(HasA<Base> &p)
{
p.A++;
}
void WorksWithAandB(HasA<HasB<Base> > &p)
{
p.A++;
p.B++;
}
int _tmain(int argc, _TCHAR *argv[])
{
HasA<Base> withA;
HasA<HasB<Base> > withAandB;
WorksWithA(withA); // OK
WorksWithAandB(withAandB); // OK
WorksWithA(withAandB); // KO, no conversion available
return 0;
}
即使不考虑构造问题,或者混合排序(HasA<HasB<Base>>
vs HasB<HasA<Base>>
),我也看不到一个好的方法来编写这个函数,除了使它成为一个模板之外。
我目前在一个没有c++ 11的环境中,但如果现代c++提供了一个解决方案,我很感兴趣。
非常感谢!
你可以使WorksWithA
成为一个模板函数,它接受任何用HasA
包装的类:
template<typename T>
void WorksWithA(HasA<T> &p)
{
p.A++;
}
在这种情况下,代码编译没有错误。
我认为你必须使你的函数模板,以及?
template <class T>
void WorksWithA(HasA<T> &p)
{
p.A++;
}
template <class T>
void WorksWithAandB(HasA<HasB<T> > &p)
{
p.A++;
p.B++;
}
由于HasA<HasB<Base>>
无法转换为HasA<Base>
.
正如其他人指出的那样,这些函数作为模板可能更好。然而,当你在做的时候,你也可以删除一些重复的代码:
template<class B>
void WorksWithA(HasA<B> &p)
{
p.A++;
}
template<class B>
void WorksWithB(HasA<B> &p)
{
p.B++;
}
template<class Has>
void WorksWithAandB(Has &p)
{
WorksWithA(p);
WorksWithB(p);
}
这里WorksWithAAndB
调用其他类型。因此:
- 您正在重用代码。
- 对于传递给
WorksWithAAndB
的类型,您正在重用编译器对传递给WorksWithA
和WorksWithB
的类型类型的检查。
你必须让WorksWithA
成为一个函数模板;没有别的办法。想想看:WorksWithA
可以与任何具有HasA
mixin的类型一起工作。
同样,在HasA
和HasB
具有接口含义的情况下,可以考虑使用继承来解决这个问题:
struct HasA
{
int A;
virtual ~HasA() = default;
};
struct HasB
{
int B;
virtual ~HasB() = default;
};
struct HasAB : HasA, HasB
{
};
struct Base : HasAB
{};
void WorksWithA(HasA &p)
{
p.A++;
}
void WorksWithAandB(HasAB &p)
{
p.A++;
p.B++;
}
这里可以用实现WithA
接口的任何类的object调用WorkWithA
,也可以用实现HasAB
接口的任何类的object调用WorksWithAandB
。
PS:不幸的是,在这个例子中,不可能用实现HasA
和HasB
的类的对象调用WorksWithAandB
而不继承HasAB
,但这可以使用模板和SFINAE来解决。
相关文章:
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 函数调用中参数的顺序重要吗
- 部分定义/别名模板模板参数
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 使用不带参数的函数访问结构元素
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 如何使用Luacneneneba API正确读取字符串和表参数
- 在派生函数中指定void*参数
- 视图中的参数推导失败:take_while
- static_assert在宏中,但也可以扩展到可以用作函数参数的东西
- 根据参数数调用 mixin 基类的构造函数
- 通过转发构造函数参数来构建基于可变参数模板的 mixin
- 如何将模板mixin作为参数