将常量值传递给模板

时间:2015-05-29 13:24:57

标签: c++ templates itk

我正在使用具有两个模板化参数的模板类

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=4dim ==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()的返回值设为const,它也无法正常工作。有没有办法做到这一点?

1 个答案:

答案 0 :(得分:2)

模板参数应该在编译时知道,不能在运行时指定它们。即使您的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链,你可以使它成为一个类并保留一个std::map函数来创建所需的对象,并让对象自己注册到它,见"Factory Pattern""Factory Pattern in C++"。这不会节省太多编码,因为您仍然需要注册每个类的代码,但是您可以将此注册移动到更好的位置并具有更多优势。

但是,我不会过分复杂化。只要您了解工厂的工作方式,您就可以从一个带有硬编码if / else链的简单工厂开始,然后,如果需要,可以使用map切换到工厂并注册,而无需更改工厂&#39 ; s客户端界面。请提前考虑这个界面。

相反,如果您的模板有很多变体,那么您不仅需要使用std::map进行实现,而且需要让编译器为您处理注册。为此,您可能需要查看描述与您的情况非常相似的"Subscribing Template Classes with Object Factories in C++",并添加一些更高级的方法。

相关问题