【发布时间】:2021-12-18 09:55:01
【问题描述】:
在我目前正在编写的课程中,我认为它的大部分私有成员变量保持const 是非常重要的。因此,我选择使用未在头文件中完全声明的初始化对象:
// 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 引入标头的命名空间,因为成员变量的声明本质上是重复的. 我正在考虑将const FooInitializer 实例本身存储为Foo 的唯一成员变量的可能性,但不幸的是,这会使上面示例中memberVariable 之类的变量int *const,而不是const int *const。他们不能C++ 容器,因为它们是由 CUDA 函数在设备内存中分配的。
有没有我没有考虑过的替代方法?
【问题讨论】:
-
“这似乎要崩溃了”是什么意思?不编译?没有按预期运行?
-
@talonmies 它无法编译。
-
我在您的问题中没有看到任何编译器错误。我们都应该猜测会发生什么吗?
-
“它们不能是 C++ 容器,因为它们是由 CUDA 函数在设备内存中分配的”。没有库就不能自己写吗?
-
@Jarod42 不幸的是,这种方法并不简单,因为我需要用
shared_ptr替换所有cudaStream_t实例,以保持我已实现的流安全功能。