标签: dependent-name

使用整数作为模板参数时编译器错误

以下代码有什么问题?

template<typename X>
struct A {
        template<int N>
        int foo() const {
                return N;
        }
};

template<typename X>
struct B {
        int bar(const A<X>& v) {
                return v.foo<13>();
        }
};

#include <iostream>
using std::cout;
using std::endl;

int main() {
        A<double> a;
        B<double> b;
        cout << b.bar(a) << endl;
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

在函数内部,B::bar编译器抱怨:

错误:类型''和'int'到二进制'operator <'的操作数无效

如果A不是模板,那么一切都很好.

c++ templates dependent-name

7
推荐指数
1
解决办法
624
查看次数

从模板函数返回的const依赖名称,const在哪里?

假设我有一个模板函数(例如foo),它返回一个const依赖类型.用于限定返回类型的选项const是将const放在typename关键字的左侧:

template<typename T>
const typename T::bar
^^^^^
foo(T const& baz) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

或在依赖类型的右侧:

template<typename T>
typename T::bar const
                ^^^^^
foo(T const& baz) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

但是如果我将const限定符放在typename关键字和依赖类型之间呢?

template<typename T>
typename const T::bar
         ^^^^^
foo(T const& baz) {
  ...
}
Run Code Online (Sandbox Code Playgroud)

如上所述,无法为GCC和CLANG编译,但令我惊讶的是VC++编译得很好.

问:

  • 这是VC++扩展吗?
  • C++标准是否说明了const在这样的上下文中放置限定符的适当位置?

c++ templates dependent-name language-lawyer c++11

7
推荐指数
1
解决办法
110
查看次数

Visual C++编译器允许dependent-name作为没有"typename"的类型?

今天我的一位朋友告诉我,以下代码在他的Visual Studio 2008上编译得很好:

#include <vector>
struct A
{
  static int const const_iterator = 100;
};
int i;
template <typename T>
void PrintAll(const T & obj)
{
  T::const_iterator *i;
}
int main()
{
  std::vector<int> v;
  A a;
  PrintAll(a);
  PrintAll(v);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我通常使用g ++,它总是拒绝传递第二个PrintAll()调用.据我所知,对于这个问题,g ++正在以标准的方式翻译模板.

那么,我的知识是错误的,还是VS2008的扩展?

c++ templates dependent-name visual-c++

5
推荐指数
1
解决办法
394
查看次数

C++依赖名称:是否需要此类型名称?

a.hpp我定义:

#include <utility>
namespace Board {
    template<int W, int H>
    struct GroupNode
    {
        using PointType = std::pair<int, int>;
        // ...
    };
}
Run Code Online (Sandbox Code Playgroud)

然后,在b.cpp我定义:

#include "a.hpp"
namespace Board {
    template<int W, int H>
    struct NodeList
    {
        using StdList = std::list < /* typename */ GroupNode<W, H>>;
    }
}
// and then use NodeList<19, 19> nl;
Run Code Online (Sandbox Code Playgroud)

上面的代码可以在gcc-6和clang-3.9上编译而不会发出任何警告.然而,克利翁2016.3抱怨cannot resolve variable GroupNodeb.cpp.取消注释typename可以驯服Clion警告,但我想知道这是否typename是必需的?如果是这样,为什么g ++/clang ++没有发出任何警告?

c++ templates dependent-name language-lawyer

5
推荐指数
1
解决办法
196
查看次数

C ++中“依赖名称”的定义是什么?

在 C++ 中,依赖名称的概念很重要,因为:

这样的名称是未绑定的,并且在模板实例化的点上查找……在模板定义的上下文和实例化点的上下文中

但是,该标准唯一说的是在[temp.dep]/2 中给出了依赖名称,指的是不合格的函数调用,基本上是为了使 ADL 能够对那些函数调用完全有效。

除了这些外,还有其他依赖名称吗?

考虑一些这样的代码,例如:

template <class T>
void foo(T t) {
    t.bar();
};
Run Code Online (Sandbox Code Playgroud)

如果有人将其bar称为“从属名称” ,根据标准,这是否在技术上不正确地使用该术语?

c++ templates dependent-name language-lawyer name-lookup

5
推荐指数
1
解决办法
159
查看次数

使用别名作为范围来获取父成员时不同的编译器行为

此代码在 Clang 和 Visual C++ 上可以正常编译,但在 GCC 上则不行:

#include <iostream>


template <class T>
struct Test {
    Test(T &t) : _t(t) {
    }
    
    void method() {
        std::cout << _t.Internal::_value << "\n";       // Doesn't work on GCC
        std::cout << _t.T::Internal::_value << "\n";    // Work on all compilers
    }

private:
    T &_t;
};

template <class T>
struct Base {
    T _value = 1;
};

template <class T>
struct Child : Base<int> {
    using Internal = Base<int>;
    
    int _value = 2;
};

int main(int …
Run Code Online (Sandbox Code Playgroud)

c++ inheritance templates dependent-name name-lookup

5
推荐指数
1
解决办法
65
查看次数

typename关键字和嵌套名称说明符

struct A{};

template <typename T>
struct B
{
    typename ::A a1; //(1)
    typename A a2; //(2): error
};

int main(){return 0;}
Run Code Online (Sandbox Code Playgroud)

为什么第一种情况是正确的,但第二种情况不正确?我不明白这种限制的含义.
无论如何,为什么第一个案例被允许?::A不是模板参数相关的名称.这有什么意义?

c++ templates dependent-name typename

4
推荐指数
2
解决办法
386
查看次数

相当于"typename",表示依赖名称确实是'模板模板参数'

我们将一部分无法找到正确语法的代码减少到最小的示例.

我们假设以下定义(不用担心"为什么";)

template <class>
class Element
{};

template <template <class> class>
class Client
{};

template <class>
struct TemplatedProvider
{
    template <class T>
    using element_template = Element<T>;
};
Run Code Online (Sandbox Code Playgroud)

现在,在C++ 11之后,我们可以使用类模板或类型别名模板来实例化Client模板.以下函数编译得很好:

void fun()
{
    Client<Provider::element_template> client;
    Client<TemplatedProvider<int>::element_template> clientBis;
}
Run Code Online (Sandbox Code Playgroud)

但是,当给出的模板参数Client是依赖名称时,我们在以下情况下找不到正确的语法:

template <class T>
void templatedFun()
{
    Client<TemplatedProvider<T>::element_template> client;
}
Run Code Online (Sandbox Code Playgroud)

Clang(用3.6测试)发出以下编译错误:

template argument for template template parameter must be a class template or type alias template
Run Code Online (Sandbox Code Playgroud)

我们可以修复这种语法吗?

c++ templates dependent-name c++11

4
推荐指数
1
解决办法
128
查看次数

为什么我不能使用QList :: size_type,因为我会使用std :: string :: size_type?(模板参数错误)

在我的for循环中声明迭代器时研究无符号与有符号整数比较警告时,我读到了这个:

尽可能使用您要比较的确切类型(例如,std::string::size_typestd::string长度比较时使用).

QList<T>想要迭代,使用上面的方法声明迭代器:

 for(QList::size_type i = 0; i < uploads.size(); i++)
 {
     //Do something
 }
Run Code Online (Sandbox Code Playgroud)

它给了我一个编译器错误:

error: 'template<class T> class QList' used without template parameters
for(QList::size_type i = 0; i < uploads.size(); i++)
Run Code Online (Sandbox Code Playgroud)

为什么我不能以同样的方式使用它?这是由我还是由Qt框架及其类型引起的?QList::size_type在这种情况下,什么是一个很好的替代品,QList::size()只需返回一个常规的旧的int,我想使用它; 但我读了上面链接的帖子,这让我不确定.

c++ qt templates dependent-name class-template

4
推荐指数
2
解决办法
157
查看次数

在不指定模板参数的情况下引用非依赖名称

考虑以下:

template<typename T> struct Foo {
     typedef void                  NonDependent;
     typedef typename T::Something Dependent;
}
Run Code Online (Sandbox Code Playgroud)

我想引用NonDependent而不指定任何模板参数,如Foo::NonDependent.

我知道我总是可以使用虚拟参数:

Foo<WhateverSuits>::NonDependent bla;
Run Code Online (Sandbox Code Playgroud)

但这很难看,而且由于它NonDependent是不变的T,我想在不依赖假人的情况下参考它.可能吗?

谢谢

c++ templates dependent-name

2
推荐指数
1
解决办法
47
查看次数

编译器将(不相关的)模板的名称与方法名称混淆

我在以下代码中有一个编译错误.似乎编译器将类方法解释set为一个模板 - 乍一看 - 与我的代码完全无关.

#include <cassert>
#include <limits>

using namespace std;

template <class T>
class ReduceScalar{

    public:
        T get() { return *r; };
        void set(T t) { *r = t; };
        void set(T* t) { r = t; };

    private:
        T* r;

};

template <class T>
class ReduceSum : public ReduceScalar<T>
{
    public:
        ReduceSum(T* target) { set(target); set(0); } // COMPILE ERROR


};
Run Code Online (Sandbox Code Playgroud)

编译器给出以下错误:

../test/../io/scalarreducers.h:34:26: error: use of class template 'set' requires template arguments
                ReduceSum(T* target) { …
Run Code Online (Sandbox Code Playgroud)

c++ templates dependent-name

1
推荐指数
1
解决办法
78
查看次数