首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么我需要在g ++中使用typedef typename而不是VS?

在C++中,typedeftypename用于定义类型别名和指定类型的嵌套成员。在某些情况下,你需要使用typedef typename而不是VS,因为这样可以确保类型别名在编译时被正确解析。

typedef用于定义类型别名,使得一个已有的类型可以用另一个名字来表示。例如:

代码语言:cpp
复制
typedef int MyInt;

这将创建一个名为MyInt的类型别名,它与int类型相同。

typename用于指定嵌套在模板中的类型。例如:

代码语言:cpp
复制
template<typename T>
class MyClass {
    typename T::NestedType myVar;
};

在这个例子中,typename用于指定T::NestedType是一个类型,而不是一个值。

在某些情况下,你需要使用typedef typename来定义类型别名,特别是当类型嵌套在模板中时。例如:

代码语言:cpp
复制
template<typename T>
class MyClass {
    typedef typename T::NestedType MyNestedType;
    MyNestedType myVar;
};

在这个例子中,typedef typename用于创建一个名为MyNestedType的类型别名,该类型别名是T::NestedType类型。这样可以确保MyNestedType在编译时被正确解析。

总之,当你需要定义一个类型别名,并且该类型嵌套在模板中时,你应该使用typedef typename而不是VS,以确保类型别名在编译时被正确解析。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

fatal error C1045: 编译器限制 : 链接规范嵌套太深

为了不耽误排查问题的时间,提前说明一下这篇文章所描述的问题范畴: 遇到的问题和 c++ 模板相关; 如果减少传递的参数的话,是有可能避免这个编译错误的; 和我使用VS 开发环境版本相关,使用...VS2013 时报错,但是使用 VS2015 及以上版本就不报错; 和我使用的平台也相关,如果改用 g++ 编译则不报错(gcc 版本为  4.9.2)。...至此,大概明白了为什么会出错了,可能就是在操作 tuple 的过程,由于使用模板递归会生成大量的中间类型,当参数数量达到一定限度时,可能会引起过度的类型嵌套,进而触发 C1045 这个编译错误。...但这个只是绕开了问题,并没有解决问题,而且的项目只能使用 VS2013(2015 需要带一坨 dll,特别零碎),所以也 pass; 对于使用 g++ 编译,这里倒是有现成的环境,而且如果能找到导致嵌套层次增加的语法因素...而且很奇怪为什么标准库在生成 tuple 过程中就没问题, qtl 在展开相同大小 tuple 的过程中就出了问题,可见 qtl 的代码质量和标准库还是有差距啊。

1.4K30

侃侃哈希表

自己便遇到了需要使用哈希表的情况,由于自己惯于使用MinGW,其中的STL(SGI版本)刚好提供了一个优雅的哈希表的模板实现,名曰hashtable,并在此基础之上进一步构建起了hash_map、hash_multimap...,所以即便在MinGW中将hashtable用的生龙活虎,但只要稍稍转变一下编程环境,譬如转至MS的VS,那么等待我的大抵也就是一大堆的未定义错误,上述的什么hashtable则更是踪迹全无……虽然有心人士早已提供了很多第三方库...hashtable,当然,追求如STL库那般的通用性并不是的编程初衷,相反,简单够用倒是的编写原则,既然如此,那么事不宜迟,就让马上动手吧 :)。...既然需要编写一个ADT,那么就先让做一个最简单的哈希表设计,首先哈希函数,以及哈希键值函数,感觉应该以模板参数提供,以此来增加灵活性,具体的当以仿函数(函数对象)的形式实现,原程序则应该提供针对部分常用类型的仿函数实现...,以方便使用

49910

两万字长文,见过最好的模板元编程文章!

普通用户对 C++ 模板的使用可能不是很频繁,大致限于泛型编程,但一些系统级的代码,尤其是对通用性、性能要求极高的基础库(如 STL、Boost)几乎不可避免的都大量地使用 C++ 模板,一个稍有规模的大量使用模板的程序...class aTMP { }; int main(){ typedef unsigned int uint; // typedef 定义类型别名不是引入新类型 typedef uint...(dependent name),C++标准规定,如果解析器在一个模板遇到一个嵌套依赖名字,它假定那个名字不是一个类型,除非显式用 typename 关键字前置修饰该名字; 和上一条 typename...C++ 模板元编程是“意外”功能,不是设计的功能,这也是 C++ 模板元编程语法丑陋的根源。...这里可能有人会想,既然循环次数固定,为什么不直接手动循环展开呢,难道就为了使用模板吗?

1.2K10

那些陌生的C++关键字

C++使用typename的情况有两种: 第一种情况是在函数模板和类模板声明。一般模板声明使用class关键字指定类型参数,后来C++支持使用typename代替class关键字。...使用格式: typename T::MyType * pvar; typedef typename T:: MyType MyType; 引发这种问题的本质原因来自于模板类型T的不确定性,和直接使用MyClass...通过typename明确的告诉编译器,这里使用的是类型。这样编译器就明确类型T引出的成员是类型,不是变量或者函数名。因此,typename使用范围也被限定在模板函数内部。...其实这些问题在目前的编译器并不存在,使用VC6.0和VS2010测试发现,无论是否加上typename程序都不会出错。对该关键字的保留大概是为了兼容旧式编译器的代码。...正因为此《C++ Primer》也假设了编译器了的工作方式: int temp=x+1; const int &cy=temp; 如果按照这种工作方式,cx引用的内存单元应该不是x的内存单元,但是在VS2010

92870

Google Mock(Gmock)简单使用和源码分析——源码分析

源码分析         通过《Google Mock(Gmock)简单使用和源码分析——简单使用的例子,我们发现被mock的相关方法在mock类已经被重新实现了,否则它们也不会按照我们的期待的行为执行...上述代码第17行定义了一个具有mutable属性的变量,之所以使用mutable是因为它可能会被使用在const类型的函数,然而该对象的方法并不一定是const的。...(A1)> { typedef A2 Argument2; typedef ::testing::tuple ArgumentTuple; typedef typename...这样两个参数版本,它从无参数版本中继承到了 typedef R Result;         从一个参数版本中继承到了 typedef A1 Argument1;         自身定义了 typedef...一般来说gmock##Method的参数约束是针对各自参数的,With则是关注于参数之间的关系。我们看下这两处约束是怎么工作的。

4.2K20

【C++】红黑树封装实现 map 和 set

set 和 map 底层都是红黑树,但这里有一个问题 – set 是K模型的容器, map 是KV模型的容器,那它们底层为什么能同样都使用红黑树呢?...的作用是告诉编译器这是一个类型,不是静态变量 typedef typename RBTree::iterator iterator; typedef typename...的作用是告诉编译器这是一个类型,不是静态变量 //使用红黑树的const迭代器来封装set的普通迭代器,从而保证K不能被修改 typedef typename RBTree<K, K, SetKeyOfT...的作用是告诉编译器这是一个类型,不是静态变量 typedef typename RBTree, MapKeyOfT>::iterator iterator...的作用是告诉编译器这是一个类型,不是静态变量 //使用红黑树的const迭代器来封装set的普通迭代器,从而保证K不能被修改 typedef typename RBTree<K, K, SetKeyOfT

80630

C++箴言:理解typename的两个含义

在c++Template很多地方都用到了typename与class这两个关键字,而且好像可以替换,是不是这两个关键字完全一样呢?       ...其实不是这样,typename另外一个作用为:使用嵌套依赖类型(nested depended name),如下所示: class MyArray          {          public:... = myarr.GetLength;     }     这个时候typename的作用就是告诉c++编译器,typename后面的字符串为一个类型名称,不是成员函数或者成员变量,这个时候如果前面没有...(想不通为什么他们不称它为 independent names(无依赖名字)。...直到 C 成为已知之前,没有任何办法知道 C::const_iterator 到底是不是一个 type(类型),当 template(模板)print2nd 被解析的时候,C 还不是已知的。

4.6K20

seqan库的使用

seqan库是进行生物序列分析的一个现代的C++库,目前有seqan2, seqan3两个版本,seqan3正在开发当中 打算应用seqan库实现一个简单的注释程序,因为seqan3暂时还未实现gtf...文件的相关操作,因此选用seqan2 seqan是header-only的库,因此无需添加lib,只要包含头文件即可使用 定义别名 为了使用简洁,定义常用类型的别名 typedef seqan::FragmentStore...使用FragmentStore来管理内存 gtf数据在内存的存储,可以被视为关系型数据库,每一行表示一个gene,因此通过唯一ID可以访问gene数据,gene数据是树状结构 想要遍历gtf数据,首先拿到根节点迭代器...found A:控制面板-应用程序-修改vs studio-勾选上通用工具的win10SDK,重新安装 Q:No CMAKE_CXX_COMPILER could be found A:删掉缓存,重新编译...TSpec, typename TConfig, typename TAnnotation, typename TKey, typename TValue> inline bool annotationGetValueByKey

51020

C++设计模式之SFINAE:用来检测类是否有某个成员函数

SFINAE是Substitution Failure Is Not An Error的缩写,直译为:匹配失败不是错误。属于C++模板编程的高级技巧,但属于模板元编程的基本技巧。...当然其实也并不是C++元编程方面的专家,只是搜集过一些常见的实现方式,然后做过一些测试。在这个过程发现有些常见的SFINAE写法是有问题的,下面探讨一下。...如果需求是要检测任意成员函数,不限定是哪个函数的话,毫无疑问,需要借助宏了。将上面的代码改变成宏的版本,push_back作为宏的一个参数,即可。 这里为什么用push_back()举例呢?...// 或 typedef int16_t No; template static No& has(...); template struct has_push_back { typedef char Yes[1]; typedef char No[2]; template

3.5K20

简单例子code

-d ABI 标记:对于每一种特性,向标记添加一个字母: 标记 含义 s 静态链接 CRT g 使用调试版本的 CRT d 构建调试版本的 Boost y 使用 Python 的特殊调试构建 p 使用...STLPort 标准库不是编译器提供的默认库 n 使用 STLPort 已被弃用的 “native iostreams” -1_34 版本标记:完整的 Boost 发布号,下划线代替点。...CRT 的 Boost(_s),默认值依赖平台 Boost_USE_DEBUG_RUNTIME 使用链接了 debug/release 版 CRT 的 Boost(_g),默认为 ON 但我发现这几个开关实际上并不是平行的各管各的...: 编译 Boost 使用VS 要和 CMake 编译工程使用VS 版本一致 来boost_1_62_0stagelib下,可以看到编译出来的 lib 文件名是包含 VC 版本号的,如: libboost_atomic-vc140...报出的错是找不到指定的 Boost 版本,其实跟 Boost 版本无关,跟编译它使用VS 版本有关。

27130

一句话帮你理解typedef的用法

来源:公众号【编程珠玑】 作者:守望先生 网站:https://www.yanbinghu.com 前言 在C语言中typedef用来给复杂声明定义别名非常的方便,不过有时候typedef在复杂声明不好理解...有人可能问了,为什么要这样,直接使用int不是更好吗?那么如果你的代码很多地方都用到了这个,但是突然有一天不再使用int,而是使用long呢?是不是直接修改typedef部分就可以了?...来源:公众号【编程珠玑】,博客地址:https://www.yanbinghu.com 一句话理解 不知道你是不是已经完全理解了前面的场景,无论理解与否,这句话都能很好的帮助你再次理解前面的内容: typedef...把变量名的位置替换为别名: typedef int Typename; 好了,你现在已经把为int取别名为Typename。...当然这可能我们平常通常使用下面这种写法: typedef struct info { char name[128]; int length; }Typename; 再来看函数指针类型,

65730

再议 C++ 11 Lambda表达式

这里有一个比较重要的一点,就是他是一个仿函数实例,不是直接一个函数。 类型 我们可以通过一个简单的示例来看它的类型。...lambda表达式的类型 为什么要关心lambda表达式的类型呢?...首先,如果用std::function绑定lambda表达式,它会走仿函数的执行流程,不是函数的。...但是对于仿函数,暂时还没有找到一个跨平台并且兼容所有主流编译器并能在不使用C++ 11的decltype关键字并在编译期对其*operator()()*的返回值不同产生差异化的完美的方案。...对于VC编译器就比较悲剧了,还好VS2010以上版本已经支持decltype。 当然还有一些比较绕的方法,可以通过手工注册一些信息来标识类型,但是这些方法个人感觉并不是很完美,这里就不列举了。

37720

使用G2O解决优化问题的简单例子

定义顶点 在该问题中,一个位置点就是图优化的一个顶点。一个顶点可以包含多个优化量。比如二维环境下的机器人位置一般是3维的(x,y,theta),即一个顶点有三个需要优化的量。...注意有时候这样的叠加操作并不是线性的。比如2D-SLAM位置步进叠加操作则不是线性的。 图片 在此问题中我们是直接线性叠加一维的距离值。 TEB的位置叠加也是线性叠加的。放置在下面以作参考。...Typedef for the block solver utilized for optimization typedef g2o::BlockSolverX TEBBlockSolver; //!...这时应该使用g2o::BlockSolverX,以便能动态适应误差项的维度。 linear solver也是可选的。...如果设置也确保不重复。但id号的顺序似乎并没有要求。 使用setVertex接口设置顶点时是有顺序的。这个顺序与边的computeError函数中使用顶点的顺序要对应起来。

1.1K30

Modern c++快速浅析

对于非模板类型参数而言,使用auto进行自动推断会方便很多 template auto是可选项不是必选项 •对于部分情景而言,使用auto能够避免不少低级错误,如Effective...result = {true, false, true}; bool value1 = result[0]; // 此时value2被推导为std::vector::reference,不是...bool auto value2 = result[1];我们能对其做出强转来修复这个问题auto value3 = static_cast(result[2]); [c++为什么不提倡使用...初学者选择typename可能会对模板有更好的了解(毕竟若模板传进来的是int,它是内置类型,看起来不是一个class) 进入正题,使用typename可以明确的告诉编译器,后面跟着的这个名字是类的类型成员...,不是数据成员(例如静态成员变量) class Foo { public: typedef int FooType; int f = 10; }; class Bar { public

15810

bullet HashMap 内存紧密的哈希表

大家好,又见面了,是全栈君。...freeFunc : btFreeDefault; } 默认情况下sAllocFunc/sFreeFunc就是malloc/free,btAlignedAllocDefault可能令人疑惑的是——为什么要多分配一点内存...自然可以明确btAlignedAllocDefault为什么多申请一点内存,申请的大小是size + sizeof(void *) + (alignment-1): 假设sAllocFunc返回的地址已经依照...size_type为std::size_t的typedef_RehashPlolicy是详细的策略类,仅仅有成员函数定义,没有数据成员(这是一种被称作Policy Based的设计范式。...这样的设计无形添加了编码和调试的复杂性。相信调试过gcc STL代码的人深有体会。 btAlignedAllocator则全然不存在这种问题: 第一。

93320
领券