enable_if+可变模板:是UB还是MSVC错误
enable_if + variadic templates: is it UB or a MSVC bug?
GCC 4.9.2、clang 3.5.0和MSVC 19(x86)按照预期编译以下内容:
#include <iostream>
#include <tuple>
#include <type_traits>
using namespace std;
template<size_t I = 0, typename... Tp>
inline typename enable_if<I == sizeof...(Tp), void>::type
tuple_for_each(tuple<Tp...> &)
{
cout << sizeof...(Tp) << endl;
}
template<size_t I = 0, typename... Tp>
inline typename enable_if<I < sizeof...(Tp), void>::type
tuple_for_each(tuple<Tp...> & t)
{
tuple_for_each<I + 1, Tp...>(t);
}
int main()
{
auto t = make_tuple(1, 2.3);
tuple_for_each(t);
}
MSVC 18(x64)报告以下内容:
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.31101 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
main.cpp
main.cpp(18) : error C2770: invalid explicit template argument(s) for 'enable_if<I<0x01,void>::type tuple_for_each(std::tuple<_Types1...> &)'
main.cpp(16) : see declaration of 'tuple_for_each'
main.cpp(24) : see reference to function template instantiation 'void tuple_for_each<0x00,int,double>(std::tuple<int,double> &)' being compiled
main.cpp(18) : error C2893: Failed to specialize function template 'enable_if<I==0x01,void>::type tuple_for_each(std::tuple<_Types1...> &)'
With the following template arguments:
'I=0x01'
'Tp={int, double}'
是UB在某个地方,还是只是一个编译器错误?(如果是后者,有什么解决办法吗?)
找到了一个解决方法:
template<size_t I = 0, typename... Tp,
typename = typename enable_if<I == sizeof...(Tp), void>::type, int = 0>
inline void tuple_for_each(tuple<Tp...> &)
{
cout << sizeof...(Tp) << endl;
}
template<size_t I = 0, typename... Tp,
typename = typename enable_if<I != sizeof...(Tp), void>::type>
inline void tuple_for_each(tuple<Tp...> & t)
{
tuple_for_each<I + 1, Tp...>(t);
}
注意I != sizeof...(Tp)
中的!=
。试试<
,你会看到:
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.31101 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
main.cpp
main.cpp(27) : fatal error C1004: unexpected end-of-file found
它本身就很壮观。(GCC和Clang都使用<
,但这次不使用MSVC19。)
尝试使用
template <bool B, typename T> using enable_alias = typename enable_if<B, T>::type;
最初的变体最终进入ICE:
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.31101 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
main.cpp
C:Program Files (x86)Microsoft Visual Studio 12.0VCINCLUDExlocnum(1105) : fatal error C1001: An internal error has occurred in the compiler.
(compiler file 'f:ddvctoolscompilercxxfeslp1coutdname.c', line 4155)
To work around this problem, try simplifying or changing the program near the locations listed above.
Please choose the Technical Support command on the Visual C++ Help menu, or open the Technical Support help file for more information
相关文章:
- enum是C++中的宏变量还是整数变量
- 如果我只是不访问queue_front节点的子节点,而是将它们推到队列中呢?还是BFS吗
- 在命名空间中定义函数还是限定函数
- 架构决策:返回std::future还是提供回调
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 异常属于C++中的线程还是进程
- 在决定是通过参考还是通过价值时,尺寸真的是一个问题吗
- 如何在C++中确定文本文件中的元素是字符还是数字
- 返回值优化:显式移动还是隐式
- 是什么原因导致它无法编译?它是声明签名还是在函数本身的实现中
- 为什么需要知道一个类是平凡的还是有平凡的构造函数
- 强枚举类型定义:Clang Bug 还是 C++11 标准不确定性?
- 'string.assign(string.data(), 5)' 是明确定义的还是 UB?
- 在哪里放置我的函数?进入我的母语 Gui 还是进入我的演示者?
- 在这种情况下,我真的复制了字节还是复制了字符?
- node-gyp 的先有鸡还是先有蛋的问题:指向依赖项中的头文件
- 使用 CTRP 时,是否访问访问父构造函数 UB 中的子属性?
- CIN是逻辑1还是0?
- C++ - 使用常量引用来延长临时成员,确定还是 UB?
- enable_if+可变模板:是UB还是MSVC错误