【发布时间】:2020-10-29 22:53:55
【问题描述】:
这是Template class type alias failing substitution in member declaration的跟进
考虑这段代码:
// A
template <typename T>
struct foo {
using type = unsigned;
template <type x>
void bar(type (&)[x]);
};
template <typename T>
template <typename foo<T>::type x>
void foo<T>::bar(type (&)[x]){}
gcc emits the following error:
<source>:13:6: error: no declaration matches 'void foo<T>::bar(foo<T>::type (&)[x])'
13 | void foo<T>::bar(type (&)[x]){}
| ^~~~~~
<source>:8:10: note: candidate is: 'template<class T> template<unsigned int x> void foo<T>::bar(foo<T>::type (&)[x])'
8 | void bar(type (&)[x]);
| ^~~
<source>:4:8: note: 'struct foo<T>' defined here
4 | struct foo {
| ^~~
Compiler returned: 1
<source>:13:14: error: out-of-line definition of 'bar' does not match any declaration in 'foo<T>'
void foo<T>::bar(type (&)[x]){}
^~~
1 error generated.
Compiler returned: 1
当我删除错误定义和候选人中相同的内容时,我得到了:
// B
template <typename T>
struct foo {
using type = unsigned;
template <type x>
void bar();
};
template <typename T>
template <typename foo<T>::type x>
void foo<T>::bar(){}
试图回答最初的问题(由 Darhuuk,稍作修改)是这样的:
// C
#include <type_traits>
template <typename T> struct length { using type = unsigned int; };
template <typename T> using length_t = typename length<T>::type;
template <typename type>
class Object {
template <length_t<Object<type>> length>
void put(type (&)[length]);
};
template <typename type>
template <length_t<Object<type>> length>
void Object<type>::put(type (&)[length]) {}
int main() {}
Clang 似乎有与原始代码和emits the error 类似的问题:
<source>:15:20: error: out-of-line definition of 'put' does not match any declaration in 'Object<type>'
void Object<type>::put(type (&)[length]) {}
^~~
1 error generated.
而gcc compiles it without complaints。
谁对C 是正确的?是 clang 的 bug 还是 gcc 的松懈?
为什么A 不能编译而B 可以?
【问题讨论】:
-
duplicate 情况略有不同,但在阅读了重复答案中链接的文章后,我相信它实际上是同一个问题
标签: c++ templates language-lawyer