![]() |
1
308
是的,使用SFINAE可以检查给定的类是否提供了特定的方法。这是工作代码:
|
![]() |
2
258
这个问题是旧的,但是用C++ 11,我们得到了一个新的方法来检查函数的存在(或者任何非类型成员的存在,真的),依赖于sFANAE:
现在来解释一下。首先,我用
expression SFINAE
排除
这个
现在,您可能需要一个特性来检查函数是否存在。幸运的是,写这个很容易。不过,请注意,你需要写一个特征 对于您可能需要的每个不同的函数名。
接着解释。第一,
请注意
这个
|
![]() |
3
158
允许C++ SFINAE 要使用这个(注意,C++ 11的特点是简单,因为它支持扩展sFANE在几乎任意的表达式——下面是与普通C++ 03编译器一起编写的):
上面的模板和宏试图实例化一个模板,给它一个成员函数指针类型,以及实际的成员函数指针。如果类型不适合,SFINAE将导致忽略模板。用法如下:
但请注意你不能就这么叫
玩得开心点。它的优点是它也适用于重载的成员函数,也适用于const成员函数(记住使用
|
![]() |
4
70
C++ 20
|
![]() |
5
54
虽然这个问题已经两年了,但我敢补充我的答案。希望它能澄清之前无可争议的优秀解决方案。我采纳了尼古拉·博内利和约翰内斯·朔布非常有用的答案,并将它们合并成一个解决方案,即IMHO,更具可读性,更清晰,不需要
我用GCC4.1.2查过了。 |
![]() |
6
30
C++ 11的简单解决方案:
更新,3年后:(这是未经测试的)。为了测试存在,我认为这会起作用:
|
![]() |
7
29
|
![]() |
8
23
这个问题已经有很长的答案了,但是我想强调一下MMOWN的评论:有一个C++ 17的建议,使它更简单。见 N4502 有关详细信息,但作为一个独立的示例,请考虑以下内容。 这部分是常量部分,放在标题中。
然后是变量部分,您可以在其中指定要查找的内容(类型、成员类型、函数、成员函数等)。在OP的情况下:
N4502号 ,显示了一个更详细的探测:
与上面描述的其他实现相比,这个实现相当简单:减少了一组工具(
live example
. 它与Clang很好,但不幸的是,在5.1之前的GCC版本遵循了对C++ 11标准的不同解释。
|
![]() |
9
10
下面是一些用法片段: *所有这一切的勇气都在更深处
检查成员函数
检查成员类
检查成员枚举
检查任何成员函数
或者
细节和核心:
创建成员检查:
创建成员变量检查:
创建成员功能检查:
创建成员类检查:
创建成员枚举检查:
创建成员检查:
|
![]() |
10
10
这是一个C++ 11解决一般问题的方法,“如果我做了X,它会编译吗?”
特质
接下来,我将使用标记发送:
比复杂的SFINAE表达式更容易维护。
上面所做的是创建一个宏
创建上述特征类。 另外,上述技术是MS所称的“expression SFINAE”的一部分,2013年的编译器失败得很厉害。
这是一个滥用大量C++特性的内联编译条件分支。这样做可能不值得,因为代码(内联代码)的好处不值得花费(在没有人理解它是如何工作的)的情况下,但是上面的解决方案的存在可能是有意义的。 |
![]() |
11
8
我在另一个线程中对此写了一个答案(与上面的解决方案不同),该线程还检查继承的成员函数: SFINAE to check for inherited member functions 下面是该解决方案的一些示例: 例1:
请注意,它甚至检查方法的常量,并且还可以处理原始类型。(我是说
例2
请注意,MyClass不必是默认可构造的,也不必满足任何特殊的概念。该技术也适用于模板成员。
|
![]() |
12
7
现在这是一个 美好的
这里有一个替代方案
Nicola Bonelli's solution
不依赖非标准
较长的comment块包含关于它如何工作(或应该如何工作)的详细信息。正如上面所说,我不确定哪种行为符合标准——我欢迎对此发表评论。 更新-2008年11月7日: Leon Timmermans 和 litb 为我指出正确的方向)。C++ 03标准如下:
所以,当MSVC或Comeau考虑
GCC和Digital Mars的行为看起来是正确的-在这两种情况下,非成员
|
![]() |
13
6
如果该方法恰好在基类中定义,则由LITB提出的标准C++解决方案将无法正常工作。 有关处理此情况的解决方案,请参阅: http://www.rsdn.ru/forum/message/2759773.1.aspx 罗马人的英译。佩雷佩利萨: http://groups.google.com/group/comp.lang.c++.moderated/tree/browse_frm/thread/4f7c7a96f9afbe44/c95a7b4c645e449f?pli=1 这真是太聪明了。但是,这个解决方案的一个问题是,如果被测试的类型不能用作基类(例如,基元类型),则会产生编译器错误 在Visual Studio中,我注意到,如果使用没有参数的方法,则需要在参数周围插入一对多余的()来推导sizeof表达式中的()。 |
![]() |
14
6
|
![]() |
15
5
我修改了中提供的解决方案 https://stackoverflow.com/a/264088/2712152 让它更一般一点。此外,由于它不使用任何新的C++ 11特性,所以我们可以使用它来与旧编译器一起使用,也应该使用MSVC。但是编译器应该启用C99来使用它,因为它使用可变宏。 以下宏可用于检查特定类是否具有特定的typedef。
以下宏可用于检查特定类是否具有特定的成员函数,或是否具有任何给定数量的参数。
|
![]() |
16
5
通过编写一个
|
![]() |
17
4
你必须确保T是一个类。看起来foo查找中的歧义是一个替换失败。我让它在gcc上运行,但不确定它是否是标准的。 |
![]() |
18
3
可用于检查类型是否支持某些“功能”的通用模板:
检查是否有方法的模板
|
![]() |
19
2
这个解决方案怎么样?
|
![]() |
20
2
真实的
方法解析排序,但不使用任何较新的c++功能(仅使用c++98功能)。
所以我想出了一个版本,它只使用sizeof():
现场演示(带有扩展的返回类型检查和vc++2010解决方案): http://cpp.sh/5b2vs
在g++编译器上运行实时演示时,请注意允许数组大小为0,这意味着使用的静态断言不会触发编译器错误,即使它失败。
|
![]() |
21
1
下面是我的版本,它以任意的arity处理所有可能的成员函数重载,包括模板成员函数,可能使用默认参数。当使用给定的参数类型(1)有效,或(2)不明确,或(3)不可行,对某个类类型进行成员函数调用时,它区分了3种相互排斥的情况。示例用法:
现在您可以这样使用它:
|
![]() |
22
1
您可以跳过C++ 14中的所有元编程,只需使用
但是,如果使用的编译器不支持泛型lambdas,则必须编写单独的函数对象:
|
![]() |
23
0
下面是一个工作代码的示例。
对于返回
|
![]() |
24
0
我也有类似的问题: 一种模板类,可以从几个基类派生,有些基类有某个成员,有些基类没有。 我的解决方法类似于“typeof”(Nicola Bonelli的)答案,但是使用decltype,它可以在msv上正确编译和运行:
|
|
25
-1
|
![]() |
SpeakX · 从模板参数类型构造类类型元组 1 年前 |
![]() |
Astor · 简化编译时二进制树类型的创建 1 年前 |
|
Ryan · 更改JS中数字的功能(出于教育目的) 1 年前 |
![]() |
Janilson · 如何解决这种多变的模板歧义 2 年前 |
![]() |
C_Rod · 在模板方法中确定STL容器中项目的数据类型 3 年前 |
![]() |
chenyuandong · Elixir中的元编程 7 年前 |
![]() |
Marcos Felipe · 基于存储的变量进行比较 7 年前 |