对命名模板参数使用不完整类型无效
Invalid use of incomplete type for named template argument
我有以下 class 模板:
template<typename T=class idType, typename U=class uType>
class f {
std::unordered_map<T::Type, float> id_; // error!
}
我正在使用依赖注入框架boost::di
,因此我需要命名我的模板参数以便能够将这些模板绑定到实际类型。当我尝试使用模板的基础类型 idType
声明哈希图时,我收到了一个错误,这让我感到很惊讶。是的,如果我使用的模板参数没有定义 Type
,我会想象一个错误,但在我的例子中我确实定义了。它们是在我包含包含上述示例的文件后定义的。
错误是:
error: invalid use of incomplete type ‘class idType’
14 | std::unordered_map<typename T::Type, float> rpc;
| ^~~
example.hpp:9:29: note: forward declaration of ‘class idType’
9 | template<typename T = class idType, typename U = class uType>
They are defined after I include the file containing the example above
是的,那是行不通的。
虽然模板和 class 定义确实有一些特定的回旋余地,因为它们有时可以引用它们之后的东西 declared/defined,但这些都是非常特殊的情况。 class 成员函数的主体可以引用它们自己的 class 中尚未声明的其他元素(本质上,编译器将成员函数定义移动到 class 定义之后).
并且模板可以引用 as-of-yet 未定义的名称...只要这些名称 依赖于 模板参数即可。
您提供的代码使用 idType
,它不是模板参数名称。 参数为T
; idType
只是该参数的默认值。如果用户提供不同的类型,您使用 idType
将忽略它。
因此,编译器必须在模板中使用时搜索 idType
,而不是在实例化时搜索。
事实上,您使用 idType
作为默认值这一事实也强加了类型需要存在于模板定义位置的要求。毕竟是你命名的;如果您命名它,它需要存在。
我有以下 class 模板:
template<typename T=class idType, typename U=class uType>
class f {
std::unordered_map<T::Type, float> id_; // error!
}
我正在使用依赖注入框架boost::di
,因此我需要命名我的模板参数以便能够将这些模板绑定到实际类型。当我尝试使用模板的基础类型 idType
声明哈希图时,我收到了一个错误,这让我感到很惊讶。是的,如果我使用的模板参数没有定义 Type
,我会想象一个错误,但在我的例子中我确实定义了。它们是在我包含包含上述示例的文件后定义的。
错误是:
error: invalid use of incomplete type ‘class idType’
14 | std::unordered_map<typename T::Type, float> rpc;
| ^~~
example.hpp:9:29: note: forward declaration of ‘class idType’
9 | template<typename T = class idType, typename U = class uType>
They are defined after I include the file containing the example above
是的,那是行不通的。
虽然模板和 class 定义确实有一些特定的回旋余地,因为它们有时可以引用它们之后的东西 declared/defined,但这些都是非常特殊的情况。 class 成员函数的主体可以引用它们自己的 class 中尚未声明的其他元素(本质上,编译器将成员函数定义移动到 class 定义之后).
并且模板可以引用 as-of-yet 未定义的名称...只要这些名称 依赖于 模板参数即可。
您提供的代码使用 idType
,它不是模板参数名称。 参数为T
; idType
只是该参数的默认值。如果用户提供不同的类型,您使用 idType
将忽略它。
因此,编译器必须在模板中使用时搜索 idType
,而不是在实例化时搜索。
事实上,您使用 idType
作为默认值这一事实也强加了类型需要存在于模板定义位置的要求。毕竟是你命名的;如果您命名它,它需要存在。