我正在尝试修改在编译时给出的模板类型但无法执行此操作。让我们看看你是否有一些想法。
让我们考虑我们有2个类A和A_test以及一个模板类B. 将实现B类,因为它有一个函数b_f(),它是内部创建模板类的对象并调用A类或A_test类的公共函数A_f()/ A_test_f()。
来自main的将创建B类obj; obj.b_f(); 但我想创建一个A_test类的对象,而不是A类。
请告诉我是否有可能。
Basicaly我想做对象注入。如果可能,请告诉我。
答案 0 :(得分:1)
到目前为止,最好的解决方案是尝试将A_test_f()重命名为与A_f()相同。
如果证明这是不可能的,我接下来要做的就是专门研究B类:
template<class AT>
class B {
public: b_f() {
AT m_A;
m_A.A_f();
};
template<>
class B<A_test> {
public: b_f() {
AT m_A;
m_A.A_test_f();
};
如果B
过于复杂,还有其他事情要尝试,但您可能想重新考虑一下您正在做的事情。如果所有其他方法都失败了,请执行我在此处编写的内容,但请将其命名为B_HELPER
而不是B
,然后b_f()可以执行:B_HELPER<AT> m_A; m_A.b_f();
这样您就不必重新编码所有内容B
。
答案 1 :(得分:0)
在编译时将依赖项注入模板的常用方法是通过类型特征。这允许通过另一个具有该类特定知识的结构或类从外部自定义模板。标准库中的示例包括std::char_traits<>
和std::iterator_traits<>
。 Boost还定义了一些,包括boost::type_traits<>
。
特征涉及为一般情况定义结构,并在必要时将其专门用于替代情况。
// general case: select method named "f".
template<class T> struct b_traits
{
typedef void(T*F)();
static const F f = &T::f;
};
// template type that forwards method selection to "b_traits" struct.
template<class AT>
class B {
public: b_f() {
AT m_A;
(m_A.*(b_traits<AT>::f))();
};
class A_test { ... };
// special case: select method named "A_test_f".
template<> struct b_traits<A_test>
{
typedef void(T*F)();
static const F f = &A_test::A_test_f;
};
int main ()
{
B<A_test> b;
b.b_f(); // will invoke "A_test::A_test_f()" rather than "A_test::f()".
}