奇怪的建议模板参数转换
strange suggested template parameter conversion
在《C++模板 - 完整指南》一书中,Vandevoorde & Josuttis建议使用以下片段来确定类型是否是类。参数是:"对于类类型,我们可以依靠观察,即指向成员类型构造 int C::* 的指针仅在 C 是类类型时才有效"作为决定类型是否为"类"类型的策略。
我有两个问题:
1)你认为这个论点有效吗?2)您将如何修改(保留策略)下面的代码片段以使其工作,因为它无法在MSVC2013上编译?
using namespace std;
template<typename T>
class IsClass
{
typedef char One;
typedef struct
{
char a[2];
} Two;
template<typename C> static One test(int C::*);
template<typename C> static Two test(...);
public:
enum { YES = (sizeof(IsClass<T>::test<T>(0) == 1)) };
};
class C{};
void main()
{
if (IsClass<C>::YES)
std::cout << "C Is a Class" << endl;
}
与评论相反,您的问题与表达 SFINAE 无关。这是沼泽标准的原始配方SFINAE:您正在检查int C::*
型的良好成型性。
在我们开始之前,你把它括起来是错误的。您希望将sizeof
应用于test
的结果,而不是==
:
enum { YES = (sizeof(IsClass<T>::test<T>(0)) == 1) };
// ^ ^
(另外,摆脱void main()
。
现在,MSVC 2013 由于某种原因尝试执行推导,并在执行限定调用时忽略指定的模板参数:
IsClass<T>::test<T>(0)
// ^^^^^^^^^^^^
这显然是一个错误。我不确定为什么它会以这种方式运行,但是MSVC前端的大部分都通过胶带固定在一起,所以我并不感到惊讶。
无论如何,您都不需要合格的呼叫。只需写test<T>(0)
并执行不合格的调用:
enum { YES = (sizeof(test<T>(0)) == 1) };
它适用于我的 MSVC 2013。
相关文章:
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 如何将向量中的可变参数转换为参数的持有者?
- c++ 构造函数 将 1 个字符串参数转换为 3 个属性
- 将空*参数转换为各种类型的参数是UB吗?
- 将可变参数模板参数转换为 JSON 字符串
- C++ 如何将函数参数转换为字符串
- 功能指针参数参数转换为const
- 避免对模板运算符过载的隐式参数转换
- 将C 方法参数转换为模板参数会因编译错误而失败
- 将参数转换为lpwstr createProcess
- 在与时间一起使用 srand 时,如果我没有time_t参数明确地将参数转换为无符号的 int 参数,这有关系吗?
- 将C++整型模板参数转换为整型"longer"型
- 将参数转换为目标类型时,复制用于直接初始化的构造函数省略
- 将命令行参数转换为qimage
- 将可变数量的参数转换为明确的数量
- SDL 方法,参数转换
- 通过错误检查将参数转换为整数
- 功能参数转换为儿童类C
- 参数转换在课堂上
- 在窗口上将格式化的 C 字符串和参数转换为 wstring