C++ 类型参数无效时无法实例化函数模板

C++ 类型参数无效时无法实例化函数模板,c++,templates,c++11,C++,Templates,C++11,我们知道以下代码: 但为什么不采取以下措施: template<typename T> void f() {} template<typename T> void g(T) {} f<void>(); //ok g<void>(); //error void f() {} void g(void) {} f(); g(); 毕竟,这是我所要求的 我在寻找一个权威的答案。法律上的论点是,void是一个不完整的类型,无法完成,因此永远不能

我们知道以下代码:

但为什么不采取以下措施:

template<typename T>
void f() {}

template<typename T>
void g(T) {}

f<void>();  //ok
g<void>();  //error
void f() {}
void g(void) {}

f();
g();
毕竟,这是我所要求的


我在寻找一个权威的答案。

法律上的论点是,
void
是一个不完整的类型,无法完成,因此永远不能用作顶级类型。与
void a比较。这有点令人困惑,因为参数列表中的
void
不是一种类型,而是一种表示没有参数的约定。

C compatibility syntarchy hack 以下是:

template<typename T>
void f() {}

template<typename T>
void g(T) {}

f<void>();  //ok
g<void>();  //error
void f() {}
void g(void) {}

f();
g();
编译时,只因为C++的语法符号保留了C兼容性的原因,即:<代码>空白>代码>:g:< /p>
void g(void) {}
此处用于表示“无参数”,而不是如预期的“一个类型为
void
”的参数”(这毫无意义)

在C++中,有时需要包含C标头,因此如果不支持该符号,则会出现问题。但这并不意味着你必须在C++代码中使用它。 C++模板 当您声明:

template<typename T>
void g(T) {}
如果要提供
g()
实现,则应提供重载:

// Original template
template<typename T>
void g(T) { /* implementation for the generic case */ }

// Code to handle g()
void g()  { /* implementation for the specific "void" case */ }
//原始模板
模板
void g(T){/*泛型case的实现*/}
//处理g()的代码
void g(){/*特定“void”案例的实现*/}
如果您想提供一个
g()
实现,您应该通过专门化提供一个模板化重载来处理无效案例:

// Original template
template<typename T>
void g(T)      { /* implementation for the generic case for g(T) */ }

// Code to handle g<void>()
template<typename T>
void g()       { /* implementation for the generic case for g() */ }

template<>
void g<void>() { /* implementation for the generic case for g<void>() */ }
//原始模板
模板
void g(T){/*实现g(T)*/}
//处理g()的代码
模板
void g()
模板
void g()

我的猜测是,这是因为模板不是文本替换系统。这很好,但当类型参数为
void
时,有什么规则?GCC47不喜欢模板中的void。它是48年前修复的。@LeonidVolnitsky:您的评论中的URL指向此主题本身,而不是gcc错误。你能不能纠正它,这样我就可以看到bug了?我很明白,但是为什么它不能被实例化为<代码>空格G(空隙){} /COD>?这是有效的吗?@纳瓦兹:我需要一个熟悉C++标准的人用法律语言来确认这个,但是<代码> G(无效){} /Cord>只适用于C兼容性,即按照您编写的
g(){}
编译。模板
template g(T){}
要求函数g具有且仅具有一个T类型的参数。
g(void)
是一个具有零参数的函数。你将可疑的语法糖(C约定)与实际的C++代码混合(事实t是参数的类型),并且在C中添加这个正确答案,这是允许的(有时会导致一些与某些代码库兼容的问题,这些代码是使用< <代码>空白> /COD>的Type文件>代码>空格F(空隙){} /代码>).我自己也知道其他的解决办法。我没有要求:-)。我的问题不是关于那个。基本上,我在寻找权威的答案,也就是说,引用《标准》中的相关文本,这显然(直接或间接)禁止了我的尝试。@Nawaz:
我自己知道替代解决方案。
:我在查看您的个人资料时是这样想的,但当时只有一个简短的答案,没有标准引用(即使现在也是如此)。我认为,一些不太熟悉C++的人希望能够获得更完整的解释,即使它缺少你想要的标准答案作为答案。
// Original template
template<typename T>
void g(T)      { /* implementation for the generic case for g(T) */ }

// Code to handle g<void>()
template<typename T>
void g()       { /* implementation for the generic case for g() */ }

template<>
void g<void>() { /* implementation for the generic case for g<void>() */ }