代码之家  ›  专栏  ›  技术社区  ›  bartop

模板参数中的双冒号为什么起作用?

  •  3
  • bartop  · 技术社区  · 6 年前

    template<class T, class... Ts> void foo();
    
    template <class T, class T::value_type>
    void foo() { }
    

    它以代码形式呈现 foo 模板函数,这是不对的,但这不是我这里的问题。我想知道为什么编译器允许这样的解释: class T::value_type 在模板参数中。我的意思是,这是非常明显的错误,我不能想出任何情况,范围运算符可能是参数名的一部分(模板或函数)。所以我有两个问题:

    1. 如果标准允许,为什么会这样?有什么用例吗?
    1 回复  |  直到 6 年前
        1
  •  6
  •   Rakete1111    6 年前

    正如评论中提到的,这是一个 elaborated type specifier . 最好用一个例子来解释:

    int main() {
        struct foo {}; // ok
        int foo = 0; // ok
    
        int test = foo; // ok, refers to variable 'foo'
        foo a; // error, 'foo' refers to variable
        struct foo b; // ok, 'struct' means that name lookup searches for classes only
    }
    

    struct/class enum typename ,因为它们分别只允许类或枚举。还要注意 类别名 在您的原始示例中是允许的!

    template<class T, class... Ts> void foo();
    
    template <class T, typename T::value_type> // Ok, value_type needs to be a type
    //                 ^^^^^^^^^^^^^^^^^^^^^^^ it's a non-type template parameter
    void foo() { }
    

    当您有一个类型和一个同名的变量时,需要使用它,或者当您有一个从属名称(即 class T::value_type , value_type class 以前,这是一个价值观。通常情况下 类别名 已使用。)

    我想不出范围运算符可能是参数名的一部分的任何情况

    你只想到这里的类型模板参数;非类型模板参数可以很好地使用范围运算符来命名类型。