在专门的模板代码中热初始化静态常量成员?
Hot to initialize static const member in specialized template code?
我目前无法按照自己的意愿设置 class 成员。我的模板 class 仅专门用于合理的整数类型(无符号和“小”)。每个专业化都需要相当大的查找 table,这仅取决于类型。所以我认为它绝对应该是静态的(和常量)并且只创建一次。
由于 C++ 没有静态构造函数,我了解到您可以创建一个 class 来执行大量初始化工作并将其作为静态成员。
我将我的代码简化为这些基础知识:
// Of this, I only want one instance per type,
// because the table can get big.
template<class T>
struct LookUp
{
static int const SIZE = 1 << (sizeof(T) << 3);
std::vector<T> table;
LookUp()
: table{ SIZE }
{
for (int i = 0; i < SIZE; ++i)
{
// Dummy code
table[i] = i;
}
}
};
// "Normal" template class with common code for all types.
template<class T>
class LbpHelper
{
typedef /*...*/ image;
};
// No functionality for the general case.
template<class T>
class Lbp
{
};
// But for this (among others) we have something.
template<>
class Lbp<uint8_t> : public LbpHelper<uint8_t>
{
typedef uint8_t value_type;
typedef Lbp::image image;
static LookUp<value_type> _lookup; // <-- This is the mean one.
public:
// Stuff...
};
初始化静态成员似乎让很多用户感到困惑,尤其是涉及到模板和专业化时。我在这里阅读了很多答案,但其中 none 解决了我的问题。
我试过
// The type of the class is the same as the type of the member class.
template<> LookUp<uint8_t> Lbp<uint8_t>::_lookup{};
template<> LookUp<uint16_t> Lbp<uint16_t>::_lookup{};
在 header 或 source 文件或 both 中。我尝试在尖括号中使用或不使用 class T
(当然在右侧使用 T
),将 template<>
全部省略,仅在 {}
中消息来源——我不知道还有什么。没有任何效果。
Visual C++ 要么告诉我 _lookup
是 不是成员,要么是 不是可以专门化的实体 或此:error C2373:“_lookup”:重新定义;不同的类型修饰符.
有人可以告诉我把什么放在哪里以便编译吗?
只需删除 template<>
位,并将静态数据成员的定义放在 .cpp 文件中:
LookUp<uint8_t> Lbp<uint8_t>::_lookup{};
LookUp<uint16_t> Lbp<uint16_t>::_lookup{};
... 而且,由于 _lookup
的类型是 class,您也可以省略 {}
;无论如何都会调用它的默认构造函数。如果您使用的是不支持统一初始化的版本,这可能会 VC++。
为什么这是正确的方法:template<>
用于引入显式专业化。您没有引入显式特化 - 您定义的是已经定义显式特化的数据成员。
这在 C++11 14.7.3/5 中涵盖:
... Members of an explicitly specialized class template are
defined in the same manner as members of normal classes, and not using the template<>
syntax. The same
is true when defining a member of an explicitly specialized member class. ...
我目前无法按照自己的意愿设置 class 成员。我的模板 class 仅专门用于合理的整数类型(无符号和“小”)。每个专业化都需要相当大的查找 table,这仅取决于类型。所以我认为它绝对应该是静态的(和常量)并且只创建一次。
由于 C++ 没有静态构造函数,我了解到您可以创建一个 class 来执行大量初始化工作并将其作为静态成员。
我将我的代码简化为这些基础知识:
// Of this, I only want one instance per type,
// because the table can get big.
template<class T>
struct LookUp
{
static int const SIZE = 1 << (sizeof(T) << 3);
std::vector<T> table;
LookUp()
: table{ SIZE }
{
for (int i = 0; i < SIZE; ++i)
{
// Dummy code
table[i] = i;
}
}
};
// "Normal" template class with common code for all types.
template<class T>
class LbpHelper
{
typedef /*...*/ image;
};
// No functionality for the general case.
template<class T>
class Lbp
{
};
// But for this (among others) we have something.
template<>
class Lbp<uint8_t> : public LbpHelper<uint8_t>
{
typedef uint8_t value_type;
typedef Lbp::image image;
static LookUp<value_type> _lookup; // <-- This is the mean one.
public:
// Stuff...
};
初始化静态成员似乎让很多用户感到困惑,尤其是涉及到模板和专业化时。我在这里阅读了很多答案,但其中 none 解决了我的问题。
我试过
// The type of the class is the same as the type of the member class.
template<> LookUp<uint8_t> Lbp<uint8_t>::_lookup{};
template<> LookUp<uint16_t> Lbp<uint16_t>::_lookup{};
在 header 或 source 文件或 both 中。我尝试在尖括号中使用或不使用 class T
(当然在右侧使用 T
),将 template<>
全部省略,仅在 {}
中消息来源——我不知道还有什么。没有任何效果。
Visual C++ 要么告诉我 _lookup
是 不是成员,要么是 不是可以专门化的实体 或此:error C2373:“_lookup”:重新定义;不同的类型修饰符.
有人可以告诉我把什么放在哪里以便编译吗?
只需删除 template<>
位,并将静态数据成员的定义放在 .cpp 文件中:
LookUp<uint8_t> Lbp<uint8_t>::_lookup{};
LookUp<uint16_t> Lbp<uint16_t>::_lookup{};
... 而且,由于 _lookup
的类型是 class,您也可以省略 {}
;无论如何都会调用它的默认构造函数。如果您使用的是不支持统一初始化的版本,这可能会 VC++。
为什么这是正确的方法:template<>
用于引入显式专业化。您没有引入显式特化 - 您定义的是已经定义显式特化的数据成员。
这在 C++11 14.7.3/5 中涵盖:
... Members of an explicitly specialized class template are defined in the same manner as members of normal classes, and not using the
template<>
syntax. The same is true when defining a member of an explicitly specialized member class. ...