将常量值传递给模板
Passing constant value to template
我正在使用具有两个模板化参数的模板class
itk::Image<PIXELTYPE,DVALUE>
在读取图像时,我将获得有关图像类型和尺寸的信息。因为有 11 个可能的类型值和 3 个维度值 (2,3,4) 每次我读取图像并且必须应用我正在执行的操作如下:
std::string type = IOBase->GetComponentTypeAsString(IOBase->GetComponentType());
const unsigned int dim = IOBase->GetNumberOfDimensions();
if(dim ==3)
{
if(type == "unsigned_char")
{
typedef itk::Image<unsigned char,3> ImageType;
//apply operation
}
else if(type == "char")
{
typedef itk::Image< char,3> ImageType;
//apply operation
}
else if(type ==....so on
}
然后我必须再次为 dim=4
和 dim ==2
执行此操作
它增加了太多代码。所以我试图通过将其值设置为 :
来避免 if else 检查暗淡
std::string type = IOBase->GetComponentTypeAsString(IOBase->GetComponentType());
const unsigned int dim = IOBase->GetNumberOfDimensions();
if(type == "unsigned_char")
{
typedef itk::Image<unsigned char,3> ImageType;
我有以下情况:
const unsigned int dimension = 3;
itk::Image<unsigned char, dimension > image;
在执行时,我必须找到类型和尺寸,然后才能创建图像。当我 运行 上面的代码工作时。但是当我尝试通过以下方式执行此操作时:
const unsigned int dimension = FunctionGetDimension();
itk::Image<unsigned char, dimension > image;
即使我将 FunctionGetDimension()
的 return 值设为 const,它也不起作用。有什么办法吗?
模板参数应该在编译时已知,不可能在 运行 时指定它们。即使您的 dim
是常量,它在编译时也是未知的。
因此无论如何您需要一些或多或少的手工逻辑来创建您需要的 Image
对象。一个常见的方法是创建一个工厂。
我假设您已经拥有最简单的工厂类型 — if/else if/else if... 子句链,每个子句返回一个不同类型的对象。你最好将它设置为一个单独的函数,如下所示:
// I assume that itk::Image subclasses a non-template BasicImage
// if this is not the case, you will need some kind of a wrapper
// you should also return unique_ptr or its friends instead of raw pointer
BasicImage* createImage(int dim, std::string type) {
if (dim == 3) {
if (type == "unsigned_char")
return new itk::Image<unsigned char, 3>();
else if...
} else if...
}
还有更高级的技术:除了硬编码 if/else 链,您可以将其设为 class 并保留 std::map
创建所需对象的函数,并让对象自己注册到它,请参阅 "Factory Pattern" and "Factory Pattern in C++"。这不会节省太多代码,因为您仍然会有注册每个 class 的代码,但是您可以将此注册移到更好的地方并获得更多优势。
但是,我不会把事情复杂化。只要你了解工厂是如何工作的,你就可以从一个带有硬编码 if/else 链的简单工厂开始,然后,如果需要,切换到使用 map
和注册的工厂而不改变工厂的客户端界面。就是提前想到了这个界面
相反,如果您的模板确实有很多变体,则不仅需要使用 std::map
实现,还需要让编译器为您处理注册。为此,您可能需要查看 "Subscribing Template Classes with Object Factories in C++",它描述了一个与您的案例非常相似的案例,并添加了一些更高级的方法。
我正在使用具有两个模板化参数的模板class
itk::Image<PIXELTYPE,DVALUE>
在读取图像时,我将获得有关图像类型和尺寸的信息。因为有 11 个可能的类型值和 3 个维度值 (2,3,4) 每次我读取图像并且必须应用我正在执行的操作如下:
std::string type = IOBase->GetComponentTypeAsString(IOBase->GetComponentType());
const unsigned int dim = IOBase->GetNumberOfDimensions();
if(dim ==3)
{
if(type == "unsigned_char")
{
typedef itk::Image<unsigned char,3> ImageType;
//apply operation
}
else if(type == "char")
{
typedef itk::Image< char,3> ImageType;
//apply operation
}
else if(type ==....so on
}
然后我必须再次为 dim=4
和 dim ==2
执行此操作
它增加了太多代码。所以我试图通过将其值设置为 :
std::string type = IOBase->GetComponentTypeAsString(IOBase->GetComponentType());
const unsigned int dim = IOBase->GetNumberOfDimensions();
if(type == "unsigned_char")
{
typedef itk::Image<unsigned char,3> ImageType;
我有以下情况:
const unsigned int dimension = 3;
itk::Image<unsigned char, dimension > image;
在执行时,我必须找到类型和尺寸,然后才能创建图像。当我 运行 上面的代码工作时。但是当我尝试通过以下方式执行此操作时:
const unsigned int dimension = FunctionGetDimension();
itk::Image<unsigned char, dimension > image;
即使我将 FunctionGetDimension()
的 return 值设为 const,它也不起作用。有什么办法吗?
模板参数应该在编译时已知,不可能在 运行 时指定它们。即使您的 dim
是常量,它在编译时也是未知的。
因此无论如何您需要一些或多或少的手工逻辑来创建您需要的 Image
对象。一个常见的方法是创建一个工厂。
我假设您已经拥有最简单的工厂类型 — if/else if/else if... 子句链,每个子句返回一个不同类型的对象。你最好将它设置为一个单独的函数,如下所示:
// I assume that itk::Image subclasses a non-template BasicImage
// if this is not the case, you will need some kind of a wrapper
// you should also return unique_ptr or its friends instead of raw pointer
BasicImage* createImage(int dim, std::string type) {
if (dim == 3) {
if (type == "unsigned_char")
return new itk::Image<unsigned char, 3>();
else if...
} else if...
}
还有更高级的技术:除了硬编码 if/else 链,您可以将其设为 class 并保留 std::map
创建所需对象的函数,并让对象自己注册到它,请参阅 "Factory Pattern" and "Factory Pattern in C++"。这不会节省太多代码,因为您仍然会有注册每个 class 的代码,但是您可以将此注册移到更好的地方并获得更多优势。
但是,我不会把事情复杂化。只要你了解工厂是如何工作的,你就可以从一个带有硬编码 if/else 链的简单工厂开始,然后,如果需要,切换到使用 map
和注册的工厂而不改变工厂的客户端界面。就是提前想到了这个界面
相反,如果您的模板确实有很多变体,则不仅需要使用 std::map
实现,还需要让编译器为您处理注册。为此,您可能需要查看 "Subscribing Template Classes with Object Factories in C++",它描述了一个与您的案例非常相似的案例,并添加了一些更高级的方法。