在C++中,是否可以使用定义中未使用的模板参数声明模板结构?
In C++, can I declare a template struct with a template parameter unused in the definition?
最近我正在阅读spirit-v2-json的源代码,我对以下代码感到困惑:
template <typename Tag> struct Literal
{
bool operator==(Literal const&) const { return true; }
bool operator< (Literal const&) const { return false; }
};
typedef Literal<struct tag_undefined> Undefined;
typedef Literal<struct tag_null> Null;
问题 1:Literal
模板中tag
参数的含义是什么?它未使用。 问题2:struct tag_undefined
和struct tag_null
甚至还没有定义,为什么我们可以将它们用作模板参数?
tag
参数的目的是区分不同的类型。它们不需要显示任何功能差异,但它们必须是不同的类。由于这种区分是tag
参数的唯一目的,并且由于它没有在模板类本身中以任何方式使用,因此可以直接在typedef
中使用不完整的原位类型。
你为什么要这样做?在上面的用例中,代码使用此模板定义两种不同的类型,Undefined
和Null
。他们本可以使用struct Null
和struct Undefined
轻松地直接创建这些类型,但是他们将不得不分别定义运算符operator=
和operator<
,这可能被认为是浪费。以这种方式使用类型标记可以达到与模板代码重用相同的效果。
如果你在后面的代码中查看这两种类型实际上是作为参数传递给boost::variant
,这是一种"多类型,单值"的方法,用于表示变量类型的值。在这里,代码希望将Undefined
和Null
的概念作为这个多类型系统中的不同类型(我猜是表示未定义或空的 json 对象)。
更新:根据 OP 请求,这里有一些代码来演示在哪里可以使用和不能使用不完整的类型:
struct incomplete_struct;
struct complete_struct{};
template<typename tag>
struct some_templ
{};
template<typename tag>
struct some_other_templ
{
tag member;
};
int main()
{
some_templ<incomplete_struct> a; //OK - incomplete template param type but not used in class so not instantiated
some_templ<struct inline_incomplete> b; //OK - as above
some_other_templ<complete_struct> c; //OK - complete_struct is complete type
some_other_templ<incomplete_struct> d; //Compile error - incomplete type, and used in template - thus instantiation of incomplete_struct is required but impossible
return 0;
}
模板参数似乎未使用,仅用于区分类型。
是的,可以使用未定义的类型作为模板参数,只要不使用它们。模板有点像编译器支持的查找和替换,并且由于不使用模板参数,因此不会将其粘贴到代码中的任何位置。
相关文章:
- 使用不带参数的函数访问结构元素
- 将结构字段的类型展开为可变模板参数
- MSVC将仅移动结构参数解释为指针
- 如何使我的 sizeof sum 结构与空参数包一起工作
- 如何传递带有通过引用传递的结构参数的函数?
- 展开可变参数模板结构
- 在类构造函数中定义结构变量的参数
- 如何在方法中传递结构参数
- 我应该在C++中将这些结构用作参数化构造函数吗?
- 带参数的数据结构的全局声明
- C++ 带有默认参数的结构,可选择在构造函数中更改
- C++-将具有引用的长参数列表重构为结构
- 为私有结构定义双参数运算符重载
- 我们可以用参数化构造函数初始化结构的数组吗?
- 关于类的想法 参数结构给定实现
- 重映射模板参数结构
- 从C 调用的编译MATLAB函数的输入参数结构
- 如何实现具有不同参数结构的纯虚拟函数
- 如何在C++中获得可更改的函数参数结构
- 函数参数 -> 结构体成员的 void* 和常量 void* 的解决方案