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

Eri*_*ric 3 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
Run Code Online (Sandbox Code Playgroud)

where 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?
    }
};
Run Code Online (Sandbox Code Playgroud)

但是,当我使用它时

USART us = USART(usart<1>::tx::A9, usart<1>::rx::A10);
Run Code Online (Sandbox Code Playgroud)

我收到了错误

error: expected ')' before 'pin_tx'
Run Code Online (Sandbox Code Playgroud)

为什么这种语法非法? 编辑: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'
Run Code Online (Sandbox Code Playgroud)

R. *_*des 14

函数参数中使用的模板参数不可推导,因为参数是依赖类型.

"但这太傻了!" 你会说; "很明显,N是1!为什么编译器不能用智能来推断它?"

考虑以下:

template<> class usart<4321> {
public:
    typedef usart<1>::tx tx;
    typedef usart<1>::rx rx;
    typedef usart<1>::ck ck;
};
Run Code Online (Sandbox Code Playgroud)

N应该是1还是4321?毕竟,usart<4321>::txusart<1>::tx是相同的类型.

如果没有检查只有usart的一个实例具有该tx成员的确切类型,编译器就无法知道N应该是什么.这将需要太多的实例化或太复杂的逻辑来证明在一般情况下不会导致实例化.当然,为这个特定情况实现一些东西可能很简单,但这对所有其他情况都不是非常有用.C++委员会只是决定不要求编译器编写者.