Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/apache-flex/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么模板参数中的双冒号有效?_C++_Language Lawyer - Fatal编程技术网

C++ 为什么模板参数中的双冒号有效?

C++ 为什么模板参数中的双冒号有效?,c++,language-lawyer,C++,Language Lawyer,在回答其中一个问题时,我遇到了如下代码: template<class T, class... Ts> void foo(); template <class T, class T::value_type> void foo() { } 模板void foo(); 模板 void foo(){} 它被表示为代码专门化foo模板函数,这是不正确的,但这不是我这里的问题。我想知道为什么编译器允许这样的构造:classt::value\u type在模板参数中。我的意思是

在回答其中一个问题时,我遇到了如下代码:

template<class T, class... Ts> void foo();

template <class T, class T::value_type>
void foo() { }
模板void foo();
模板
void foo(){}
它被表示为代码专门化
foo
模板函数,这是不正确的,但这不是我这里的问题。我想知道为什么编译器允许这样的构造:
classt::value\u type
在模板参数中。我的意思是,这显然是错误的,我不能想出任何情况,范围运算符可能是参数名称的一部分(模板或函数)。所以我有两个问题:

  • 标准是否允许它,或者它是编译器中的一个疏忽
  • 如果标准允许,为什么会这样?有任何用例吗

  • 正如在评论中提到的,这是一个很好的例子。最好用一个例子来解释:

    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
    ,因为它们分别只允许类或枚举。还请注意,原始示例中允许使用
    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() { }
    
    模板void foo();
    模板//确定,值类型必须是类型
    //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^这是一个非类型模板参数
    void foo(){}
    
    当您有一个类型和一个具有相同名称的变量时需要它,或者当您有一个从属名称时需要指定它是什么(即在
    class T::value\u type
    中,
    value\u type
    是一个类,如果之前没有
    class
    ,它将是一个值。通常使用
    typename

    我想不出作用域运算符可能是参数名称的一部分的任何情况


    这里只考虑类型模板参数;非类型模板参数可以很好地使用scope操作符来命名类型。

    我认为
    class T::value\u type
    是一种新的类型。在此声明中,第二个模板参数必须是类类型的not type参数。如果我错了,请纠正我:此
    class T::value\u type
    只是类型
    T::value\u type
    的未使用模板参数,对吗?@bartop它也是未命名的,是:)