c++ - 为什么不能推导嵌套在模板类中的枚举的模板参数?

标签 c++ templates c++11

我有一些这样命名的常量:

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>::txusart<1>::tx是同一类型。

如果不检查只有一个 usart 实例具有与 tx 完全相同的类型,编译器就无法知道 N 应该是什么。成员。这要么需要太多的实例化,要么需要太复杂的逻辑来证明在一般情况下没有实例化会导致这种情况。当然,针对这个特定案例实现一些东西可能很简单,但对所有其他案例来说并不是很有用。 C++ 委员会简单地决定不要求编译器编写者这样做。

关于c++ - 为什么不能推导嵌套在模板类中的枚举的模板参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14559359/

相关文章:

c++ - 在 cygwin 中尝试通过 g++ 编译程序时收到 "access is denied "消息

c++ - 如何添加文件以在代码块中构建和读取它们?

c++ - 使用来自 Cython 构造函数的参数初始化 C++ 对象

java - 在 Velocity 模板中按名称引用 map

c++ - 模板类的 typedef 声明

c++ - C++ 中的位图图像操作

c++ - "Refresh"一个 lambda 对象

c++ - 为什么我不能将此正则表达式返回字符串转换为整数或直接转换为整数? (C++)

c++ - 如何使用模板表达成员之间的约束?

c++ - 使用继承 move 分配/构造函数会抛出范围外的错误