使用 typealias 代替定义中 class 中定义的 typedef
Using typealias in place of typedef defined in class in definition
为什么编译失败?我正在尝试减少重复次数,因为在实际代码中 class 名称很大,而 type
实际上是一个很长的名称
#include <vector>
template<typename T>
struct S {
using type = std::vector<T>;
type f() const;
};
template<typename T>
using type_t = typename S<T>::type;
template <typename T>
type_t<T> S<T>::f() const { }
上面的代码失败如下
<source>:17:14: error: no declaration matches 'type_t<T> S<T>::f() const'
17 | type_t < T > S < T >::f() const
| ^~~~~~~
<source>:8:10: note: candidate is: 'S<T>::type S<T>::f() const'
8 | type f() const
| ^
<source>:4:8: note: 'struct S<T>' defined here
4 | struct S
| ^
这是一个 GCC 错误;最近的(1) 已确认打开的错误报告似乎是:
- Bug 69348: 别名声明不能在声明符的限定符内使用
这突出表明 GCC 拒绝以下格式正确的程序:
template <class T>
struct X {
int foo();
};
template <class T>
using foo2 = X<T>;
template <class T>
int foo2<T>::foo()
{
}
带有错误信息
error: invalid use of incomplete type 'struct X<T>'
(1) 扫描 GCC:s bugzilla,似乎有许多与别名模板相关的“拒绝有效”(open/unconfirmed) 错误报告,在大多数报告中 clang 是报告接受(可以说是格式正确的)示例程序。
我不记得确切原因,但我知道这与编译器解析类型名称和符号的顺序有关...
您可以通过稍微更改声明的结构来使其工作。
由于我不知道这对您来说有多大可能,所以我包含了一些变体。
#include <vector>
#include <iostream>
template <typename T>
struct S
{
using type = std::vector<T>;
auto f() const -> decltype(type());
auto g() const -> decltype(type());
decltype(type()) h() const;
};
template <typename T>
using type_t = typename S<T>::type;
template <typename T>
auto S<T>::f() const -> decltype(type())
{
std::cout << "foo" << std::endl;
type_t<T> t;
return t;
}
template <typename T>
using other_type_t = decltype(typename S<T>::type());
template <typename T>
auto S<T>::g() const -> other_type_t<T>
{
std::cout << "bar" << std::endl;
other_type_t<T> t;
return t;
}
template <typename T>
using last_type_t = decltype(typename S<T>::type());
template <typename T>
last_type_t<T> S<T>::h() const
{
std::cout << "foobar" << std::endl;
last_type_t<T> t;
return t;
}
int main(){
S<int> s;
auto t = s.f();
auto r = s.g();
auto l = s.h();
return 0;
}
输出:
Program returned: 0
Program stdout
foo
bar
foobar
为什么编译失败?我正在尝试减少重复次数,因为在实际代码中 class 名称很大,而 type
实际上是一个很长的名称
#include <vector>
template<typename T>
struct S {
using type = std::vector<T>;
type f() const;
};
template<typename T>
using type_t = typename S<T>::type;
template <typename T>
type_t<T> S<T>::f() const { }
上面的代码失败如下
<source>:17:14: error: no declaration matches 'type_t<T> S<T>::f() const'
17 | type_t < T > S < T >::f() const
| ^~~~~~~
<source>:8:10: note: candidate is: 'S<T>::type S<T>::f() const'
8 | type f() const
| ^
<source>:4:8: note: 'struct S<T>' defined here
4 | struct S
| ^
这是一个 GCC 错误;最近的(1) 已确认打开的错误报告似乎是:
- Bug 69348: 别名声明不能在声明符的限定符内使用
这突出表明 GCC 拒绝以下格式正确的程序:
template <class T> struct X { int foo(); }; template <class T> using foo2 = X<T>; template <class T> int foo2<T>::foo() { }
带有错误信息
error: invalid use of incomplete type 'struct X<T>'
(1) 扫描 GCC:s bugzilla,似乎有许多与别名模板相关的“拒绝有效”(open/unconfirmed) 错误报告,在大多数报告中 clang 是报告接受(可以说是格式正确的)示例程序。
我不记得确切原因,但我知道这与编译器解析类型名称和符号的顺序有关...
您可以通过稍微更改声明的结构来使其工作。
由于我不知道这对您来说有多大可能,所以我包含了一些变体。
#include <vector>
#include <iostream>
template <typename T>
struct S
{
using type = std::vector<T>;
auto f() const -> decltype(type());
auto g() const -> decltype(type());
decltype(type()) h() const;
};
template <typename T>
using type_t = typename S<T>::type;
template <typename T>
auto S<T>::f() const -> decltype(type())
{
std::cout << "foo" << std::endl;
type_t<T> t;
return t;
}
template <typename T>
using other_type_t = decltype(typename S<T>::type());
template <typename T>
auto S<T>::g() const -> other_type_t<T>
{
std::cout << "bar" << std::endl;
other_type_t<T> t;
return t;
}
template <typename T>
using last_type_t = decltype(typename S<T>::type());
template <typename T>
last_type_t<T> S<T>::h() const
{
std::cout << "foobar" << std::endl;
last_type_t<T> t;
return t;
}
int main(){
S<int> s;
auto t = s.f();
auto r = s.g();
auto l = s.h();
return 0;
}
输出:
Program returned: 0
Program stdout
foo
bar
foobar