对命名模板参数使用不完整类型无效

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,它不是模板参数名称。 参数TidType 只是该参数的默认值。如果用户提供不同的类型,您使用 idType 将忽略它。

因此,编译器必须在模板中使用时搜索 idType,而不是在实例化时搜索。

事实上,您使用 idType 作为默认值这一事实也强加了类型需要存在于模板定义位置的要求。毕竟是你命名的;如果您命名它,它需要存在。