是否可以在编译时编辑模板名称?

时间:2011-08-17 18:20:53

标签: c++ windows

我正在尝试修改在编译时给出的模板类型但无法执行此操作。让我们看看你是否有一些想法。

让我们考虑我们有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我想做对象注入。如果可能,请告诉我。

2 个答案:

答案 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()".
}