使用 typedef 将多个模板 class 组合成一个 class
Combining multiple template classes to one class using typedef
我有以下一段代码。
让我们有函数声明和实现
分开。
#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 来帮助缩短
模板参数说明。
首先,实现class定义本身的功能会更好。然后,你的问题就完全消失了。
如果您必须在外部实现函数,您可以对简单的 return 类型使用类似于下面的宏。:
#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;}
但是,对于复杂的 return 类型,该逻辑将失效。假设您有:
template <class T1, class T2>
class A
{
public:
explicit A() {}
void foo() const;
int bar() const;
char const* (*)(int, int) bar2() const;
};
我不知道是否有办法将 return 类型捕获为宏参数。
正在使用
A_FUNC((char const* (*)(int, int)), bar2)() const { return NULL;}
导致各种编译器错误。
在我自己的代码中,我还将声明与实现分开。有时我只需要代码知道存在一个模板,更多时候我想让它很容易看到接口是什么。
我已经用宏解决了这个繁琐的输入问题。然而,解决方案很复杂。
如果您的 return 类型没有逗号(即不包括 std::unordered_map<int, std::string>
等情况),这里有一个简单的实用宏:
#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 { ... }
对于越来越多的模板参数,您可以使用 TEMPLATE1
、TEMPLATE3
等等。但是,您也可以将其拆分为两个宏:一个生成类型列表,一个生成特化。我已经完成了它们,但相信我,即使我不喜欢它。不是缺乏预处理技巧,我可以告诉你没有令人满意的方法来避免冗长。
我有以下一段代码。 让我们有函数声明和实现 分开。
#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 来帮助缩短 模板参数说明。
首先,实现class定义本身的功能会更好。然后,你的问题就完全消失了。
如果您必须在外部实现函数,您可以对简单的 return 类型使用类似于下面的宏。:
#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;}
但是,对于复杂的 return 类型,该逻辑将失效。假设您有:
template <class T1, class T2>
class A
{
public:
explicit A() {}
void foo() const;
int bar() const;
char const* (*)(int, int) bar2() const;
};
我不知道是否有办法将 return 类型捕获为宏参数。
正在使用
A_FUNC((char const* (*)(int, int)), bar2)() const { return NULL;}
导致各种编译器错误。
在我自己的代码中,我还将声明与实现分开。有时我只需要代码知道存在一个模板,更多时候我想让它很容易看到接口是什么。
我已经用宏解决了这个繁琐的输入问题。然而,解决方案很复杂。
如果您的 return 类型没有逗号(即不包括 std::unordered_map<int, std::string>
等情况),这里有一个简单的实用宏:
#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 { ... }
对于越来越多的模板参数,您可以使用 TEMPLATE1
、TEMPLATE3
等等。但是,您也可以将其拆分为两个宏:一个生成类型列表,一个生成特化。我已经完成了它们,但相信我,即使我不喜欢它。不是缺乏预处理技巧,我可以告诉你没有令人满意的方法来避免冗长。