Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么模板专门化没有';我不在gcc工作_C++_Templates_Metaprogramming - Fatal编程技术网

C++ 为什么模板专门化没有';我不在gcc工作

C++ 为什么模板专门化没有';我不在gcc工作,c++,templates,metaprogramming,C++,Templates,Metaprogramming,我想写用微控制器GPIO操作的类型表方法 我想创建GPIO的列表并只选择特定端口的管脚。 所以,GetPinWithPort模板有专门检查提供类型的功能 模板 结构列表 { 使用type=tlist; }; 模板类调试; #定义MAKE_端口(名称、ID)\ 类名\ {\ 公众:\ 静态空集(uint32_t v){}\ 静态空洞重置(uint32_t v){}\ 枚举{id=id}\ }; 使_端口(端口“A”); 使_端口(端口B,'B'); 模板 类TPin { 公众: 静态void Se

我想写用微控制器GPIO操作的类型表方法

我想创建GPIO的列表并只选择特定端口的管脚。 所以,
GetPinWithPort
模板有专门检查提供类型的功能

模板
结构列表
{
使用type=tlist;
};
模板类调试;
#定义MAKE_端口(名称、ID)\
类名\
{\
公众:\
静态空集(uint32_t v){}\
静态空洞重置(uint32_t v){}\
枚举{id=id}\
};
使_端口(端口“A”);
使_端口(端口B,'B');
模板
类TPin
{
公众:
静态void Set(){PORT::Set(1应该是

template <typename TPort, uint8_t N>  // or auto
struct GetPinWithPort<TPort, TPin<TPort, N>>

TPin
它的类型是:

TPin<Porta, 1>
TPin

因此,gcc可能会将
TPin
解析为
TPin
,然后使专业化失败。

在这一行中,使用pina=GetPinWithPort::type;
1的类型为int而不是uint32\u t。因此,您可以实例化
GetPinWithPort
(非专用定义),而不是
GetPinWithPort

以下是专门化将正确的模板参数传递给TPin时的情况:

template <typename TPort, uint8_t N>
struct GetPinWithPort<TPort, TPin<TPort, N>>
{
    using type = TPin<TPort, N>;
};
模板
结构GetPinWithPort
{
使用类型=TPin;
};
以下是它的使用方法:

using pina = GetPinWithPort<Porta, TPin<Porta, static_cast<uint8_t>(1)> >::type;
使用pina=GetPinWithPort::type;

这是因为C++对使用模板的类型非常严格:允许类型非常有限的转换。

您只声明了Debug没有在任何地方定义。@ KAPIL是故意的。这是一个技巧,让编译器给你一个错误,给你精确的模板。结果我会期待。不确定GCC是怎么回事,但将
template
更改为
template
可以让它工作。但不知道为什么需要它。Visual Studio正确使用模板,GCC有一个奇怪的结果,这很疯狂。我原本认为VS一定是错误的,但如果clang也能工作,那么这可能是一个错误实际上,GCC有一个bug。@NathanOliver:当试图专门研究
std::array
时,可能有一个
std::array
的dupe,它的类型是
int
,而不是
std::size\t
。你能说一下为什么会这样吗?MSV和clang都适用于
uint32\t
。我已经添加了一些解释,但我是不是语言的律师,而是我感觉它比C++规范更高,或者什么,因为未签名int是依赖于实现的,而不是作为标准建立的。如果我记得正确,GCC选择最小(存储明智)。如果在创建时未指定固定宽度,则可以在初始化时键入。如果将专门化更改为使用
int
则仍然无效:@NathanOliver您是对的。我应该先自己尝试一下。此操作有效:
TPin<TPort, uint32_t>
TPin<Porta, 1>
template <typename TPort, uint8_t N>
struct GetPinWithPort<TPort, TPin<TPort, N>>
{
    using type = TPin<TPort, N>;
};
using pina = GetPinWithPort<Porta, TPin<Porta, static_cast<uint8_t>(1)> >::type;