为什么在这种情况下会出现 "is not a constant expression" 错误? (模板)
Why do I get "is not a constant expression" error in this case ? (templates)
我正在尝试用 C++ 为我的 ITK 图像实现某种 numpy.where()。 ITK 的方式似乎是与函子。我对模板不是很有经验,所以我的整个方法可能有缺陷,但我的做法是:
using MASK_IMAGE_TYPE = itk::Image<unsigned short, 3>;
template<class T, T value, T if_equal, T if_n_equal> class WhereFunctor
{
private:
T v = value;
T e = if_equal;
T n = if_n_equal;
public:
WhereFunctor() = default;
~WhereFunctor() = default;
inline T operator()(const T& in_value)
{
return in_value == value ? if_equal : if_n_equal;
}
};
template<typename T> typename T::Pointer where(
typename T::Pointer& img,
typename T::PixelType value,
typename T::PixelType if_equal,
typename T::PixelType if_n_equal)
{
auto filter = itk::UnaryFunctorImageFilter<T, T, WhereFunctor<typename T::PixelType, value, if_equal, if_n_equal>>::New();
filter->SetInPlace(false);
filter->SetInput(img);
filter->Update();
typename T::Pointer ret_img = filter->GetOutput();
return ret_img;
}
当我尝试调用此 where 函数时:
auto img = where<MASK_IMAGE_TYPE>(my_image, 0, 1, 0);
,我收到以下错误:
: In instantiation of ‘typename T::Pointer where(typename T::Pointer&, typename T::PixelType, typename T::PixelType, typename T::PixelType) [with T = itk::Image<short unsigned int, 3>; typename T::Pointer = itk::SmartPointer<itk::Image<short unsigned int, 3> >; typename T::PixelType = short unsigned int]’:
:23:55: required from here
:58:124: error: ‘value’ is not a constant expression
58 | auto filter = itk::UnaryFunctorImageFilter<T, T, WhereFunctor<typename T::PixelType, value, if_equal, if_n_equal>>::New();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
:58:124: note: in template argument for type ‘short unsigned int’
:58:124: error: ‘if_equal’ is not a constant expression
:58:124: note: in template argument for type ‘short unsigned int’
:58:124: error: ‘if_n_equal’ is not a constant expression
:58:124: note: in template argument for type ‘short unsigned int’
我想我知道这样的错误可能是由于编译类型的类型不确定性造成的,但在这种情况下我不明白它是从哪里来的。
您有很多不必要的模板参数。你可以按照它在相应测试中完成的方式进行操作。定义您的 function, set it via filter->SetFunctor() 并调用 Update()
.
按照建议,更正后的代码版本为:
template<class T> class WhereFunctor
{
private:
T v = 0;
T e = 0;
T n = 1;
public:
WhereFunctor() = default;
WhereFunctor(T value, T if_equal, T if_n_equal)
: v(value), e(if_equal), n(if_n_equal)
{}
~WhereFunctor() = default;
inline T operator()(const T& in_value)
{
return in_value == v ? e : n;
}
inline bool operator!=(const WhereFunctor<T>& other) { return v!=other.v || e!=other.e || n!=other.n; }
};
template<typename T>
typename T::Pointer where(typename T::Pointer& img, typename T::PixelType value, typename T::PixelType if_equal, typename T::PixelType if_n_equal)
{
auto filter = itk::UnaryFunctorImageFilter<T, T, WhereFunctor<typename T::PixelType>>::New();
filter->SetFunctor(WhereFunctor<typename T::PixelType>(value, if_equal, if_n_equal));
filter->SetInPlace(false);
filter->SetInput(img);
filter->Update();
typename T::Pointer ret_img = filter->GetOutput();
return ret_img;
}
我正在尝试用 C++ 为我的 ITK 图像实现某种 numpy.where()。 ITK 的方式似乎是与函子。我对模板不是很有经验,所以我的整个方法可能有缺陷,但我的做法是:
using MASK_IMAGE_TYPE = itk::Image<unsigned short, 3>;
template<class T, T value, T if_equal, T if_n_equal> class WhereFunctor
{
private:
T v = value;
T e = if_equal;
T n = if_n_equal;
public:
WhereFunctor() = default;
~WhereFunctor() = default;
inline T operator()(const T& in_value)
{
return in_value == value ? if_equal : if_n_equal;
}
};
template<typename T> typename T::Pointer where(
typename T::Pointer& img,
typename T::PixelType value,
typename T::PixelType if_equal,
typename T::PixelType if_n_equal)
{
auto filter = itk::UnaryFunctorImageFilter<T, T, WhereFunctor<typename T::PixelType, value, if_equal, if_n_equal>>::New();
filter->SetInPlace(false);
filter->SetInput(img);
filter->Update();
typename T::Pointer ret_img = filter->GetOutput();
return ret_img;
}
当我尝试调用此 where 函数时:
auto img = where<MASK_IMAGE_TYPE>(my_image, 0, 1, 0);
,我收到以下错误:
: In instantiation of ‘typename T::Pointer where(typename T::Pointer&, typename T::PixelType, typename T::PixelType, typename T::PixelType) [with T = itk::Image<short unsigned int, 3>; typename T::Pointer = itk::SmartPointer<itk::Image<short unsigned int, 3> >; typename T::PixelType = short unsigned int]’:
:23:55: required from here
:58:124: error: ‘value’ is not a constant expression
58 | auto filter = itk::UnaryFunctorImageFilter<T, T, WhereFunctor<typename T::PixelType, value, if_equal, if_n_equal>>::New();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
:58:124: note: in template argument for type ‘short unsigned int’
:58:124: error: ‘if_equal’ is not a constant expression
:58:124: note: in template argument for type ‘short unsigned int’
:58:124: error: ‘if_n_equal’ is not a constant expression
:58:124: note: in template argument for type ‘short unsigned int’
我想我知道这样的错误可能是由于编译类型的类型不确定性造成的,但在这种情况下我不明白它是从哪里来的。
您有很多不必要的模板参数。你可以按照它在相应测试中完成的方式进行操作。定义您的 function, set it via filter->SetFunctor() 并调用 Update()
.
按照建议,更正后的代码版本为:
template<class T> class WhereFunctor
{
private:
T v = 0;
T e = 0;
T n = 1;
public:
WhereFunctor() = default;
WhereFunctor(T value, T if_equal, T if_n_equal)
: v(value), e(if_equal), n(if_n_equal)
{}
~WhereFunctor() = default;
inline T operator()(const T& in_value)
{
return in_value == v ? e : n;
}
inline bool operator!=(const WhereFunctor<T>& other) { return v!=other.v || e!=other.e || n!=other.n; }
};
template<typename T>
typename T::Pointer where(typename T::Pointer& img, typename T::PixelType value, typename T::PixelType if_equal, typename T::PixelType if_n_equal)
{
auto filter = itk::UnaryFunctorImageFilter<T, T, WhereFunctor<typename T::PixelType>>::New();
filter->SetFunctor(WhereFunctor<typename T::PixelType>(value, if_equal, if_n_equal));
filter->SetInPlace(false);
filter->SetInput(img);
filter->Update();
typename T::Pointer ret_img = filter->GetOutput();
return ret_img;
}