您能否转发声明未声明模板 class 的显式特化?
Can you forward declare an explicit specialization of undeclared template class?
在我目前正在写的class中,我认为非常重要的一点是它的大部分私有成员变量都保持const
。因此,我选择使用未在 header 文件中完全声明的初始化 object:
// foo.h
template<typename T>
class Foo {
const int *const memberVariable; // Important detail: pointer to a heap-allocated array
const int otherMemberVariable;
...
Foo(class FooInitializer &&initializer);
public:
Foo(int constructorArgument, ...);
}
// foo.cpp
class FooInitializer {
int *memberVariable; // Important detail: pointer to a heap-allocated array
int otherMemberVariable;
...
FooInitializer(int constructorArgument, ...) : memberVariable(constructorArgument, ...), ... {
cuda_function(&memberVariable, &otherMemberVariable, ..., constructorArgument, ...);
...
}
}
Foo::Foo(FooInitializer &&initializer) : memberVariable(std::move(initializer.memberVariable)), ... {}
Foo::Foo(int constructorArgument, ...) : Foo({constructorArgument, ...}) {}
但是,如果构造函数参数或成员变量之一必须是类型参数类型,这似乎会崩溃:
// foo.h
template<typename T>
class Foo {
const int *const memberVariable; // Important detail: pointer to a heap-allocated array
const int otherMemberVariable;
...
Foo(class FooInitializer<T> &&initializer);
public:
Foo(int constructorArgument, ...);
}
// foo.cpp
template<typename T>
class FooInitializer {
int *memberVariable;
int otherMemberVariable;
...
FooInitializer(int constructorArgument, ...) : memberVariable(constructorArgument, ...), ... {
cuda_function(&memberVariable, &otherMemberVariable, ..., constructorArgument, ...);
...
}
}
template<typename T>
Foo<T>::Foo(FooInitializer<T> &&initializer) : memberVariable(std::move(initializer.memberVariable)), ... {}
template<typename T>
Foo<T>::Foo(int constructorArgument, ...) : Foo({constructorArgument, ...}) {}
我尝试了一些替代语法(例如Foo<T>::Foo(template<> FooInitializer<T> &&initializer)
无济于事。我反对临时堆分配,我试图避免将FooInitializer
引入header的命名空间,因为成员变量的声明基本上重复。我正在考虑将 const FooInitializer
实例本身存储为 Foo
的唯一成员变量的可能性,但不幸的是,这会使变量像 [=18] =] 在上面的示例中 int *const
,而不是 const int *const
。它们不能是 C++ 容器,因为它们是由 CUDA 函数在设备内存中分配的。
有没有我没有考虑过的替代方法?
Foo(class FooInitializer<T> &&initializer);
尽管您可以在函数声明 (int bar(struct S s);
) 中声明(非模板)classes,但我认为您不能对模板 classes 进行声明。
I am trying to avoid introducing FooInitializer
into the header's namespace due to essentially duplicate declarations of the member variables.
但你仍然可以转发声明class:
template <typename> class FooInitializer;
template<typename T>
class Foo
{
// ...
Foo(FooInitializer<T> &&initializer);
// ...
};
在我目前正在写的class中,我认为非常重要的一点是它的大部分私有成员变量都保持const
。因此,我选择使用未在 header 文件中完全声明的初始化 object:
// foo.h
template<typename T>
class Foo {
const int *const memberVariable; // Important detail: pointer to a heap-allocated array
const int otherMemberVariable;
...
Foo(class FooInitializer &&initializer);
public:
Foo(int constructorArgument, ...);
}
// foo.cpp
class FooInitializer {
int *memberVariable; // Important detail: pointer to a heap-allocated array
int otherMemberVariable;
...
FooInitializer(int constructorArgument, ...) : memberVariable(constructorArgument, ...), ... {
cuda_function(&memberVariable, &otherMemberVariable, ..., constructorArgument, ...);
...
}
}
Foo::Foo(FooInitializer &&initializer) : memberVariable(std::move(initializer.memberVariable)), ... {}
Foo::Foo(int constructorArgument, ...) : Foo({constructorArgument, ...}) {}
但是,如果构造函数参数或成员变量之一必须是类型参数类型,这似乎会崩溃:
// foo.h
template<typename T>
class Foo {
const int *const memberVariable; // Important detail: pointer to a heap-allocated array
const int otherMemberVariable;
...
Foo(class FooInitializer<T> &&initializer);
public:
Foo(int constructorArgument, ...);
}
// foo.cpp
template<typename T>
class FooInitializer {
int *memberVariable;
int otherMemberVariable;
...
FooInitializer(int constructorArgument, ...) : memberVariable(constructorArgument, ...), ... {
cuda_function(&memberVariable, &otherMemberVariable, ..., constructorArgument, ...);
...
}
}
template<typename T>
Foo<T>::Foo(FooInitializer<T> &&initializer) : memberVariable(std::move(initializer.memberVariable)), ... {}
template<typename T>
Foo<T>::Foo(int constructorArgument, ...) : Foo({constructorArgument, ...}) {}
我尝试了一些替代语法(例如Foo<T>::Foo(template<> FooInitializer<T> &&initializer)
无济于事。我反对临时堆分配,我试图避免将FooInitializer
引入header的命名空间,因为成员变量的声明基本上重复。我正在考虑将 const FooInitializer
实例本身存储为 Foo
的唯一成员变量的可能性,但不幸的是,这会使变量像 [=18] =] 在上面的示例中 int *const
,而不是 const int *const
。它们不能是 C++ 容器,因为它们是由 CUDA 函数在设备内存中分配的。
有没有我没有考虑过的替代方法?
Foo(class FooInitializer<T> &&initializer);
尽管您可以在函数声明 (int bar(struct S s);
) 中声明(非模板)classes,但我认为您不能对模板 classes 进行声明。
I am trying to avoid introducing
FooInitializer
into the header's namespace due to essentially duplicate declarations of the member variables.
但你仍然可以转发声明class:
template <typename> class FooInitializer;
template<typename T>
class Foo
{
// ...
Foo(FooInitializer<T> &&initializer);
// ...
};