我有一些这样命名的常量:
template<int n> class usart {
private:
usart();
public:
enum class tx {};
enum class rx {};
enum class ck {};
};
template<> class usart<1> {
public:
enum class tx { A9 = gpio::A9, C4 = gpio::C4 };
enum class rx { A10 = gpio::A10, C5 = gpio::C5 };
enum class ck { A8 = gpio::A8 };
};
// two more of these
其中 gpio
只是一个简单的整数枚举。
我想在另一个文件中对我的类强制实现某种类型安全:
class USART {
public:
template<int N>
USART(typename usart<N>::tx pin_tx, typename usart<N>::rx pin_rx) {
//This signature enforces correct pins with types, doesn't it?
}
};
但是,当我使用它时
USART us = USART(usart<1>::tx::A9, usart<1>::rx::A10);
我收到错误
error: expected ')' before 'pin_tx'
为什么这个语法是非法的?
编辑:typename
当我尝试实例化该类时,现在出现此错误:
error: no matching function for call to 'USART::USART(usart<1>::tx, usart<1>::rx)' note: template<int N> USART::USART(typename usart<N>::tx, typename usart<N>::rx) note: template argument deduction/substitution failed: note: couldn't deduce template parameter 'N'
最佳答案
函数参数中使用的模板参数不可推导,因为参数是依赖类型。
“但这很愚蠢!”你会说; “很明显,N 是 1!为什么编译器的智慧不能推断出这一点?”
考虑以下几点:
template<> class usart<4321> {
public:
typedef usart<1>::tx tx;
typedef usart<1>::rx rx;
typedef usart<1>::ck ck;
};
N 应该是 1 还是 4321?毕竟,usart<4321>::tx
和 usart<1>::tx
是同一类型。
如果不检查只有一个 usart 实例具有与 tx
完全相同的类型,编译器就无法知道 N 应该是什么。成员。这要么需要太多的实例化,要么需要太复杂的逻辑来证明在一般情况下没有实例化会导致这种情况。当然,针对这个特定案例实现一些东西可能很简单,但对所有其他案例来说并不是很有用。 C++ 委员会简单地决定不要求编译器编写者这样做。
关于c++ - 为什么不能推导嵌套在模板类中的枚举的模板参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14559359/