- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试弄清楚这个 SFINAE 概念,但我必须说我发现它真的很令人困惑。我理解为什么如果编译器可以根据模板类型/args 推断并选择正确的函数,那将是一个巨大的优势,但我不知道那是否是 SFINAE,因为首字母缩略词代表的是 IMO。也许你可以帮我解决这个问题,但现在这实际上不是我的问题。
我的问题是:我从这里查找并尝试了一个 SFINAE 示例: https://en.cppreference.com/w/cpp/language/sfinae
特别是告诉您模板类型 C 是对象类型还是内部类型(int、bool 等)的那个。我正在谈论的示例代码是这样的:
template<typename T>
class is_class {
typedef char yes[1];
typedef char no [2];
template<typename C> static yes& test(int C::*); // selected if C is a class type
template<typename C> static no& test(...); // selected otherwise
public:
static bool const value = sizeof(test<T>(0)) == sizeof(yes);
};
然后我想尝试一下,所以我稍微修改了一下,没有做任何可能影响使用哪个函数的更改,最后得到以下代码。我使用 Visual Studio 2017。我不认为它运行 C++2017,但它不能落后太多。不用说,它两次显示“不是类”:
#include<cstdio>
#define say(x) printf(#x "\n")
template<typename T>
void f(int T::*) {
printf("f<T>();\n");
}
template<class T>
void f(T) {
printf("normal f();\n");
}
class Hejsa {
public:
int A;
Hejsa() { A = 2; }
};
template<typename T>
class is_class {
public:
typedef char yes[1];
typedef char no[2];
template<typename C> static yes& test(int C::*) {
say("is class"); return new yes;
}; // selected if C is a class type
template<typename C> static no& test(...) {
say("is not class"); no _n; return _n;
}; // selected otherwise
public:
static bool const value = sizeof(test<T>(0)) == sizeof(yes);
};
int main() {
int var1 = 9;
Hejsa var2;
is_class<Hejsa>::test<Hejsa>(var1);
is_class<Hejsa>::test<Hejsa>(var2);
f(var1);
f(var2);
getchar();
}
这是什么原因造成的?能不能尽量少改,让它“工作”,也就是让test<Hejsa>(var1);
说“不是类”和test<Hejsa>(var2)
说“是类”? (“Hejsa”是一个丹麦语词,意思是“你好”或“你好”之类的意思;P)
提前致谢
托马斯
最佳答案
SFINAE 如何创造这些特征:
首先,简单的typedef来确保不同的大小
typedef char yes[1]; // sizeof == 1
typedef char no [2]; // sizeof != 1 (2 actually)
然后,2 个重载函数(声明):
template<typename C> static yes& test(int C::*);
template<typename C> static no& test(...);
int C::*
是 int
类型成员的指针.只有当 C
时它才是良构的是一个类(即使该类没有 int
BTW 类型的成员)。对于其他类型(如 float
),它的格式不正确。
...
是接受额外参数的省略号(如 printf
系列)。
所以当C
是一个类,两个函数都对test<C>(0)
有效
yes& test(int C::* m); // with m = nullptr
no& test(...); // with ... taking int 0
重载解析规则做第一个被选中。 (所以返回类型是 yes&
)。
但是当C
不是一个类(比如说 float
)
对于 template<typename C> static yes& test(int C::*);
, 用替换我们会得到 yes& test(int float::*);
由于函数是模板,失败取决于模板,我们没有出现错误,而是简单地忽略了重载集中的那个函数(它不是错误)。
只有省略号函数对 test<C>(0)
有效(所以返回类型是 no&
)。
现在,使用 sizeof(test<T>(0))
允许询问编译器它将选择哪个重载(无需调用函数,因此不需要定义)。
我们将最终结果存储在静态成员is_class::value
中.
一旦你有了特征,可能的用法包括在重载或直接 SFINAE 中分配标签:
template <typename T>
std::enable_if_t<is_class<T>::value> foo() { std::cout << "a class"; }
template <typename T>
std::enable_if_t<!is_class<T>::value> foo() { std::cout << "a class"; }
std::enable_if_t<bool>
当 bool 为假时格式错误,并被 void
替代否则。
关于c++ - SFINAE 示例不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50891078/
今天有小伙伴给我留言问到,try{...}catch(){...}是什么意思?它用来干什么? 简单的说 他们是用来捕获异常的 下面我们通过一个例子来详细讲解下
我正在努力提高网站的可访问性,但我不知道如何在页脚中标记社交媒体链接列表。这些链接指向我在 facecook、twitter 等上的帐户。我不想用 role="navigation" 标记这些链接,因
说现在是 6 点,我有一个 Timer 并在 10 点安排了一个 TimerTask。之后,System DateTime 被其他服务(例如 ntp)调整为 9 点钟。我仍然希望我的 TimerTas
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我就废话不多说了,大家还是直接看代码吧~ ? 1
Maven系列1 1.什么是Maven? Maven是一个项目管理工具,它包含了一个对象模型。一组标准集合,一个依赖管理系统。和用来运行定义在生命周期阶段中插件目标和逻辑。 核心功能 Mav
我是一名优秀的程序员,十分优秀!