【问题标题】:Combining multiple template classes to one class using typedef使用 typedef 将多个模板类组合成一个类
【发布时间】:2015-06-16 18:43:33
【问题描述】:

我有以下代码。 让我们有函数声明和实现 分开。

#include <iostream> 

class Y1 {}; 
class Y2 {}; 

template <class T1, class T2> 
class A
{   
    public:
        explicit A();
        void foo() const;
        int bar() const;
};  

template <class T1, class T2> 
A<T1, T2>::A() {}

template <class T1, class T2> 
void A<T1, T2>::foo() const {}

template <class T1, class T2> 
int A<T1, T2>::bar() const {}

int main() {
    A<Y1, Y2> a;
    a.foo();


    A<Y1, Y2> *a2 = new A<Y1, Y2>();
    a2->foo();

    return 0;
}   

每次写都很痛苦

template <class T1, class T2>

对于每个对象声明和函数声明。

有人可以帮助使用宏或 typedef 来缩短 模板参数说明。

【问题讨论】:

  • 可以内联定义成员函数。
  • 我明白了。但让我们将结构和实现分开。
  • 正如@juanchopanza 所说......由于是模板,它们很可能必须与类定义位于同一位置。
  • 我想说的是,对于模板来说,将它们分开是很常见的,因为你从中获得的收益很少。

标签: c++ templates macros typedef


【解决方案1】:

首先,最好在类定义本身中实现函数。然后,您的问题就完全消失了。

如果你必须在外面实现函数,你可以使用类似下面的宏来简单的返回类型。:

#define A_FUNC(ret, name) \
template <class T1, class T2> \
ret A<T1, T2>::name

A_FUNC(void, foo)() const {}

A_FUNC(int, bar)()  const { return 0;}

但是,对于复杂的返回类型,该逻辑将失效。假设你有:

template <class T1, class T2> 
class A
{   
    public:
        explicit A() {}
        void foo() const;
        int bar() const;
        char const* (*)(int, int) bar2() const;
};  

我不知道是否有办法将该返回类型捕获为宏参数。

使用

A_FUNC((char const* (*)(int, int)), bar2)()  const { return NULL;}

导致各种编译器错误。

【讨论】:

  • +1 表示返回函数指针的示例,但 -1 表示建议将声明与成员函数的定义混合使用。有很好的理由将它们分开。第一,在某些情况下你只需要声明,甚至是模板;例如,这足以知道成员的类型。更实际的是,没有实现,接口看起来更干净
  • @EdMaster,是实现类定义内还是类定义外的功能,看来是见仁见智了。对于简单的函数,我很少(如果有的话)在类之外实现这些函数。对于复杂的函数,在类定义之外实现它们是有意义的。
【解决方案2】:

在我自己的代码中,我还将声明与实现分开。有时我只需要代码就知道存在模板,更多时候我想让它很容易看到接口是什么。

我已经用宏解决了这个繁琐的打字问题。但是,解决方案很复杂。

如果您的返回类型没有逗号(即不包括 std::unordered_map&lt;int, std::string&gt; 等情况),这里有一个简单的实用程序宏:

#define TEMPLATE2(returnType, className, type1, type2) \
   template<typename type1, typename type2> returnType className<type1, type2>::

你可以这样使用它:

TEMPLATE2(, A, T1, T2)::A() { ... }

TEMPLATE2(int, A, T1, T2)::bar() const { ... }

对于越来越多的模板参数,您可以使用TEMPLATE1TEMPLATE3 等等。但是,您也可以将其拆分为两个宏:一个生成类型列表,一个生成特化。我已经完成了,但相信我,即使我不喜欢它。不是缺乏预处理技巧,我可以告诉你没有令人满意的方法来避免冗长。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多