c++ - c++ type alias not working when testing specialization
问题描述
Using C++, trying to implement: is_specialization_of
template<typename T, template<typename...> class Template>
struct is_specialization_of : std::false_type {};
template<template<typename...> class Template, typename... Tn>
struct is_specialization_of<Template<Tn...>, Template> : std::true_type {};
template<typename... Tn>
struct tstruct {};
template<typename... Tn>
using ustruct = tstruct<Tn...>;
int main( int argc, char **argv )
{
printf( "test u<int> against u, return %s\n", is_specialization_of<ustruct<int>, ustruct>::value ? "true" : "false" );
printf( "test u<int> against t, return %s\n", is_specialization_of<ustruct<int>, tstruct>::value ? "true" : "false" );
printf( "test t<int> against u return %s\n", is_specialization_of<tstruct<int>, ustruct>::value ? "true" : "false" );
printf( "test t<int> against t, return %s\n", is_specialization_of<tstruct<int>, tstruct>::value ? "true" : "false" );
getchar();
return 0;
}
Return:
test u<int> against u, return false
test u<int> against t, return true
test t<int> against u return false
test t<int> against t, return true
Looks like the type alias is not considered exactly as the original type
I am using Visual Studio Community 2017
Microsoft (R) C/C++ Optimizing Compiler Version 19.15.26732.1 for x64
However when trying to compile the same code using gcc, it returns:
test u<int> against u, return true
test u<int> against t, return true
test t<int> against u return true
test t<int> against t, return true
Is there anything I can do for a workaround?
解决方案
Looks like the type alias is not considered exactly as the original type, or did I miss something?
The alias specialization is exactly the type it stands for. But the alias tempalte is an entirely distinct template. The reason for your output is specified by [temp.alias]
1 A template-declaration in which the declaration is an alias-declaration declares the identifier to be an alias template. An alias template is a name for a family of types. The name of the alias template is a template-name.
2 When a template-id refers to the specialization of an alias template, it is equivalent to the associated type obtained by substitution of its template-arguments for the template-parameters in the type-id of the alias template.
If we examine your test cases with the above two paragraphs in mind, we see that:
"test
u<int>
againstu
" -ustruct<int>
is equivalent to specifyingtstruct<int>
directly. Andtstruct<int>
is not a specialization ofustruct
. The trait needs to evaluate to false."
test u<int>
againstt
" - Hereustruct<int>
is again equivalent to specifyingtstruct<int>
directly. Andtstruct<int>
is a specialization oftstruct
. The trait should report true."test
t<int>
againstu
" -tstruct<int>
is not a specialization ofustruct
, like we observed previously. The trait should report false."test
t<int>
againstt
" - Should report true.
All your tests, when run in MSVC, conform to what the C++ standard says they should do. GCC is not conforming here, it's a compiler bug.
推荐阅读
- assembly - 带有 OR 和 AND 符号的 MIPS CODE 数学表达式
- r - 安装 R 包 fgsea:download.file 中的错误
- java - 它是如何工作的?洗牌阵列
- php - 如何将输入字段放入图像的区域协调中
- python - 如何与python中脚本给出的反向shell交互?
- tomcat - Microsoft IIS 10 - Apache Tomcat 7 反向代理 Windows 身份验证问题
- python - 删除 JSON 对象中的键,并添加不同的键
- android - setState 不工作 - React Native 地图不显示用户当前位置
- java - 当域是简单名称时,java https客户端不发送cookie
- svelte - 部署到 Netlify 的 Sapper 应用在某些路由上返回 404