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

SFINAE:检测成员变量是否存在不适用于g++

SFINAE,也被称为“Substitution Failure Is Not An Error”,是C++模板元编程中的一个重要概念。它允许我们根据类型特征来选择适当的函数或类模板。在编译时,当试图对一个模板进行实例化时,如果某个成员函数或成员变量无法在目标类型中找到,编译器并不会报错,而是将该候选模板从候选者列表中剔除。这使得我们能够通过模板特化和重载来选择最佳的模板实例。

SFINAE常常与模板元编程中的类型特征结合使用,例如使用std::enable_ifstd::void_t等类型特征工具。这些特征工具允许我们根据某些条件在编译时决定是否选择模板的实例化。在使用SFINAE时,我们可以根据类型特征判断某个成员变量是否存在,从而在编译时做出相应的处理。

尽管SFINAE是C++模板元编程中的一个有用工具,但它不适用于g++编译器。g++编译器在编译过程中会在遇到无法解析的成员变量时抛出错误,而不是使用SFINAE将其从候选者列表中剔除。因此,检测成员变量是否存在的操作不适用于g++编译器。

如果需要在g++中检测成员变量是否存在,可以考虑使用其他技术,例如SFINAE的替代方案或使用其他编译器(如Clang)来实现该功能。

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

相关·内容

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

针对类中特定成员函数的检测其实在工作中也可能用到。C++中可以用SFINAE技巧达到这个目的。...在这个过程中,我发现有些常见的SFINAE写法是有问题的,下面探讨一下。 举个例子,我们来check一下C++标准库的类中有没有push_back()成员函数。...因为网上能找到的各种SFINAE的实现版本中,很多对于push_back的检测都是有问题的。 而以上列举这两种,都能准确检测出string、vector、list中的push_back()。...下面列举一个常见但某些情况下会存在问题的SFINAE范本: class Base { }; class Drive:Base { public: void hello() {} }; template...has_hello::value << std::endl; std::cout ::value << std::endl; } OK,这个用来检测类中是否

4.1K20
  • 未来已来:从SFINAE到concepts

    这是一种 C++ 中的编译期技术,用于在模板实例化过程中,当尝试进行模板参数的替换时,如果出现了替换失败(通常是由于找不到相应的成员函数、操作符等),不会导致编译错误,而是会选择其他可行的模板特化。...概念提供了一种更加清晰和简洁的方法,用于规定模板类型参数必须满足的条件,以替代传统的通过模板特化和SFINAE(Substitution Failure Is Not An Error)技术实现的模板约束方式...std::convertible_to 是 C++20 中的一个概念(Concept),用于指定类型 T 是否可以隐式转换为类型 U。...成员变量 判断一个对象是否存在某个成员变量: #include #include #include template <typename...成员函数 如果要判断某个类是否存在某个成员函数,那么可以像如下这么写: #include #include #include template

    22110

    【笔记】《深入理解C++11》(上)

    __cplusplus 返回cpp版本, C语言则无定义, 用于混合编译 新编译特性 中提供assert()宏, 用于运行时断言; static_assert()用于编译期断言,...初始化列表的效果总是慢于就地初始化, 但也快过在构造函数中进行赋值 注意: 非常量的静态变量依然要在头文件外定义从而保证在程序中只存在一个 sizeof()可以对类成员表达式使用了 类模板也可以声明友元了...原因和extern变量一样, 普通的模板只存在于对应文件的.o中, 如果一个模板文件被多个文件实例化就会产生多份重复代码, 没有extern的话此时重复的模板会冲突....最终可以用is_pod::value直接判断是否POD 非受限联合 C++11后, 任何非引用类型都可以成为union的成员(包括函数), 因此称为非受限联合 不允许静态成员变量存在 union的一些默认函数将被删除..., 例如当存在非POD成员且这个成员有非平凡的构造函数时, 这个union的默认构造将被删除 匿名的union对外是开放的, 因此放在类的声明中可以按照构造函数的不同而初始化为不同的类型, 此时类被称为枚举式的类

    1.9K20

    C++ 新特性学习(四) — Bind和Function

    + 4.6.1中测试通过 木有错,这是C++,并且很方便地实现了委托 这就是传说中的绑定库和增强型的函数对象 接下来一个一个来 Bind 可用于绑定函数、成员函数、函数对象、成员变量 这是老标准中...另外,std::bind还可以用于绑定成员变量,和函数结构,绑定函数变量的方法类似成员函数,绑定函数结构的方法类似普通函数 再来一个std::bind稍微复杂一点的应用的例子,和算法库配合使用 void...“C”的函数(如: std::strcmp)也不支持(经过检测G++和VC++都没问题) 支持”stdcall”, “cdecl”, “__fastcall” 和 “pascal” 前缀,但是绑定这些函数时要注意加一些定义...std::function同样支持函数、成员函数、函数变量和函数结构。 std::function和std::bind配合使用时是把std::bind返回的结果作为函数对象使用的。...operator()(int x, int y) const { return x / y; }; }; std::function f = int_div(); 但是成员变量成员函数稍有不同

    2.4K10

    C++奇淫巧技之SFINAE

    SFINAE 技术,即匹配失败不是错误,英文Substitution Failure Is Not An Error,其作用是当我们在进行模板特化的时候,会去选择那个正确的模板,避免失败 看个具体的例子...is_pointer::value); // prints 1 } 通过定义4个重载的 is_ptr函数,3个是接受不同的指针参数,另一个则包括了其他的所有参数, IntPtr 是一个变量指针...FooMemberPtr 是一个成员属性指针 FuncPtr 是一个函数指针 接着我们来看下 muduo 库中的一段代码: template struct has_no_destroy...static int32_t test(...); const static bool value = sizeof(test(0)) == 1; }; // 其作用就是用来判断是否有...printf("%d\n",has_no_destroy::value); printf("%d\n",has_no_destroy::value); } 其作用主要是判断是否

    53230

    C语言边角料:结构体中指针类型的成员变量,它的类型重要吗?

    本着强迫症要消灭一切警告的做法,最终定位到:是结构体内部, 指向结构体类型的指针成员变量导致的问题。 这个问题,也许永远不会碰到,之所以被我赶上了,应该是因为某个时候手贱, 误碰了键盘导致。...正常的代码 比较简单:结构体 struct _Data2_ 的第 2 个成员变量是一个指针,指向的数据类型是结构体 struct _Data1_。...此时它并并没确认该指针所指向的数据类型是否存在,它只是为 next 保留了 4 个字节的内存空间(32位系统)。...dn中的成员变量a。...不过,从中我们也看到了一个现象:gcc编译器在面对结构体时,主要关心的是结构体在内存空间中所占用的空间大小,对其内部指向结构体类型的指针,并没有严格的检查是否存在g++ 在这一点就做的严谨一些了。

    53640

    C++20初体验——concepts

    参数列表用于创建一系列一定类型的变量,在requirements中使用。这些变量并不真实存在(只有语法功能),它们的作用域到后面的}为止。...由于参数列表中的变量不实际存在,这个表达式当然也不会被求值。...如果模板参数代入时出现了不存在的类型或变量,该约束仅仅是不被满足,而不会产生编译错误。 约束可以用于函数模板、类模板和成员函数,非模板类的非模板成员函数除外。...函数模板与类模板的约束是类似的,只有满足约束时模板才能实例化;对于成员函数的约束,如果它作用于模板类的模板参数,当约束不满足时,并不是类模板不能被实例化,而是实例化后的模板类没有这个成员函数: #include...ci.f(1); ci.g(); Container cd; cd.f(1); cd.g(); // error } 像特化和偏特化一样,concept之间存在的包含关系也能用于重载决议

    1.4K10

    C语言服务器编程必备常识

    g++参数-pg产生gprof性能信息,gprof好像是g++自带的 (gdb)make使你能不退出gdb就能产生就重新产生可执行文件 , shell 不退出gdb就执行shell file a.out...并发不适用于计算密集型,因为任务切换会降低效率,适用于IO密集型,如经常读写文件、访问数据库。 池就是预先静态分配资源,到时可以快速使用。 避免了对内核的频繁访问。...最简单的二进制信号量,只有0和1.用一个普通变量模拟是不行的,因为检测和减1无法原子完成。 linux上的线程使用clone系统调用创建的进程模拟的。...pthread_mutexattr_setpshared() 加锁-》pthread_cond_wait暗含解锁,确保能检测到条件变量的任何变化。 有些函数不可重入主要是因为内部使用了静态变量。...pthread_create当线程函数是类的成员函数时,必须为静态函数【确保没对象时也可以使用】,由于静态成员函数只能访问静态成员,要访问动态成员需要函数内部用单例或将类的对象作为参数传给函数。

    1.3K20

    【C++】——入门基础知识超详解

    命名空间 在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。...使用 using 将命名空间中某个成员引入:适用于只需要频繁使用命名空间中的某几个成员的情况。...由于 Windows 下 VS 的修饰规则过于复杂,而 Linux 下 G++ 的修饰规则简单易懂,我们使用 G++ 演示修饰后的名字。...引用 6.1 引用概念 引用是C++中一个重要的概念,它并不是定义一个新变量,而是给已经存在变量取了一个别名。引用和被引用的变量共享同一块内存空间,因此引用不会占用额外的内存空间。...for 循环后的括号由冒号 : 分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围。

    11410

    性能优化利器之constexpr

    从概念上理解的话,constexpr即常量表达式,重点在表达式字段,用于指定变量或函数可以在常量表达式中使用,可以(或者说一定)在编译时求值的表达式,而const则为了约束变量的访问控制,表示运行时不可以直接被修改...好了,既然示例一(使用const)可以在编译期进行求值,而constexpr也可以在编译期求值,那么直接用constexpr替换示例一种的const是否可行?...函数 constexpr也可以修饰普通函数或者成员函数,其实这块在上一节已经有提过,示例如下: constexpr int Add(const int a, const int b) { return...SFINAE 和 std::enable_if不是很了解的,建议自行阅读哈)。...t.value * t.value操作,而对于一个int来说并没有value这个变量,所以编译失败。

    40910

    C++之父子之间冲突的解决

    一、父子之间的冲突: 1、思考 子类中是否可以定义父类中的同名成员? 如果可以的话,那么该怎样区分呢? 如果不可以的话,那么又是为啥呢?...return 0; } 代码是否可以编译通过,我们来看一下编译器编译的结果: root@txp-virtual-machine:/home/txp# g++ test.cpp root@txp-virtual-machine...2、父子之间冲突的规则: 子类可以定义父类中的同名成员 子类中的成员将隐藏父类中的同名成员 父类中的同名成员依然存在于子类中 通过作用域分辨符(::)访问父类中的同名成员,例如: Child c; c.mi...string> using namespace std; namespace A {     int g_i = 0; } namespace B {     int g_i = 1;// 同名的全局变量...重载函数的本质为多个不同的函数 函数名和参数列表是唯一的标识 函数重载必须发生在同一个作用域中,这一点非常关键 (2)子类中定义的函数是否能够重载父类中的同名函数呢?

    45840

    C++中使用vs2015和g++对new开辟的堆内存是否初始化的分析

    1 示例程序 这里用下面这个C++程序作为演示,在后面两个小节中分别使用g++和vs2015来编译。...<< endl; delete obj1; A *obj2 = new A(); //如果类A中没有自定义的构造函数(调用编译器合成的默认构造函数),但是接着会对内存(各个成员变量...+编译器进行编译并执行 无论是否将DEFAULTFUN的值设置为1(即打开类A中的默认构造函数),在使用g++编译器编译并执行的输出结果都如下图所示。...因此,图中类A的两个对象obj1和obj2对应的数据成员i_value的值都为0,而且整型指针变量指向偏移量为10的那个整数也都是0。...对比类A的对象obj1和obj2的数据成员的输出值可以得出结论:如果类A中没有自定义的构造函数,那么new A和new A()会调用编译器合成的默认构造函数,但是只有new A()会对这块内存(各个成员变量

    11810
    领券