如何将模板化类实例作为模板参数传递给另一个模板?
How do you pass a templated class instance as a template parameter to another template?
我有一个类模板,我想将其实例作为模板参数传递给另一个类模板。如:
typedef Pin<(uint16_t)&PORTB,0> B0;
typedef Pin<(uint16_t)&PORTB,1> B1;
然后我想像这样传递它们:
Indicator<B0,B1> Ind1;
我正在使用的引脚类模板:
template <uint16_t tPort, uint8_t tBit>
class Pin
{
public:
static constexpr uint16_t Port = tPort;
static constexpr uint16_t DDR = tPort-1;
static constexpr uint16_t PIn = tPort-2;
static constexpr uint8_t Bit = tBit;
static constexpr void Toggle()
{
*reinterpret_cast<uint16_t*>(Port) ^= (1<<Bit);
}
static constexpr void PullHigh()
{
*reinterpret_cast<uint16_t*>(Port) |= (1<<Bit);
}
static constexpr void PullLow()
{
*reinterpret_cast<uint16_t*>(Port) &= ~(1<<Bit);
}
static constexpr void SetOutput()
{
*reinterpret_cast<uint16_t*>(DDR) &= ~(1<<Bit);
}
static constexpr void SetInput()
{
*reinterpret_cast<uint16_t*>(DDR) |= (1<<Bit);
}
static constexpr void SetHighImpedance()
{
*reinterpret_cast<uint16_t*>(Port) &= ~(1<<Bit);
*reinterpret_cast<uint16_t*>(DDR) &= ~(1<<Bit);
}
static constexpr bool Read()
{
return (*reinterpret_cast<uint16_t*>(PIn) & (1<<Bit));
}
};
我已经能够将它们传递给模板函数。我认为模板模板参数可能是答案。但是一直无法让它工作...
非类型模板参数不限于整数。您似乎传递了uint16_t
只是将其重新解释为指针。相反,您可以将指针本身作为模板参数传递。
另请注意,constexpr
上下文中不允许reinterpret_cast
。
在编译时传递指针如下所示:
template <uint16_t* tPort, uint8_t tBit>
class Pin
{
// ...
};
它将像这样使用:
using B1 = Pin<&PORTB, 1>;
假设您要编写Indicator
模板类,它将如下所示:
template<typename P1, typename P2>
struct Indicator {
// ...
};
如果您担心强制P1
和P2
成为引脚,可以通过创建类型特征并对其进行断言来完成:
// Base case
template<typename>
struct is_pin : std::false_type {};
// Case where the first parameter is a pin
template <uint16_t* tPort, uint8_t tBit>
struct is_pin<Pin<tPort, tBit>> : std::true_type {};
然后,使用您的断言:
template<typename P1, typename P2>
struct Indicator {
static_assert(is_pin<P1>::value && is_pin<P2>::value, "P1 and P2 must be pins");
// ...
};
然后,要使函数接收Indicator
,您可以执行以下操作:
// Pass type only, and use static members
template<typename IndicatorType>
void do_stuff() {
IndicatorType::stuff();
}
// Pass an instance of the class
template<typename IndicatorType>
void do_stuff(IndicatorType indicator) {
indicator.stuff();
}
这些函数的调用方式如下:
// Passing only the type
do_stuff<Indicator<B1, A1>>();
// Passing an instance
Indicator<B1, A1> indicator;
do_stuff(indicator);
这一次我不会担心IndicatorType
不是一个指标。任何充当指示符的类都将被接受,如果不能以与指标相同的方式使用,则会发生编译时错误。这将使指标的执行方式具有更大的灵活性。
另外,我建议您阅读更多或更深入的有关C++模板的教程。有时被忽视,它是C++最重要和最复杂的特征之一。
相关文章:
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 修改函数中的指针(将另一个指针作为参数传递)
- 如何将一个类的函数作为另一个类的另一个函数的参数传递
- C++重载函数,一个采用基类的参数,另一个采用派生类的参数
- 如果模板参数是另一个模板的实例化,则键入特征测试
- 将可变参数从一个函数传递到另一个函数
- 将一个宏传递到另一个宏而不是直接传递内容时会出现不需要的额外"空"参数
- 如何调用参数由另一个函数生成的函数?
- 如何在 VC++ 中通过引用传递另一个对象的方法(错误 C2664)
- 将函数上调整到基类参数的另一个
- 可以将算术表达式作为参数传递给一个函数来描述其中的逻辑
- 传递参数作为另一个函数的参数函数
- C libcurl-使用上一个卷曲的响应作为参数到另一个卷曲的参数
- 将模板变化函数及其参数传递到一个函数
- C++传递另一个方法作为参数
- C++:为默认方法参数调用另一个方法
- 如何让每个线程传递另一个参数
- C++:将部分专用模板的类型参数作为另一个模板类的成员类型
- 将多个参数从另一个类传递给线程函数
- 为什么 GCC 不允许我将模板参数用于另一个模板的参数?