如何根据模板参数制作代码生成

How to make code generation depending on template arguments?

本文关键字:数制 代码生成 参数 何根      更新时间:2023-10-16

如果模板参数不符合标准(某些值或类型(,我可以防止模板类的函数的产生吗?这可以通过使用C 代码和无预处理器指令来实现吗?

这种功能既不应在标头或体内可用。这种情况似乎有点人为,但我还没有找到解决方案。

示例类(简化 - 无构造函数等(:

myClass.h

template<int Dimension, typename TPixelType = float>
    class MyClass
{
    void DoSomething();
    void DoAnotherThing(); // this function should only be available if Dimension > 2
}

myClass.cxx

template< int Dimension, typename TPixelType> void MyClass::DoSomething()
{...}
// pseudocode: if Dimension <= 2 do not compile next function
template< int Dimension, typename TPixelType> void MyClass::DoAnotherThing() 
{
    MethodNotToBeCompiled(); // The function I don't want to be executed
}

testMyClass.cxx

int main()
{
    auto myclass0 = MyClass<2>();
    myclass0.DoSomething(); // OK
    myclass0.DoAnotherThing(); // (wanted) error - function not available
    auto myclass1 = MyClass<3>();
    myclass1.DoSomething(); // OK
    myclass1.DoAnotherThing(); // OK
}

在C XX中是否可以?还是有其他方法以外的方法?

template <int Dimension, typename TPixelType> void MyClass::DoSomething()  {/*...*/}
// if Dimension <= 2 do not compile next function
template <int Dimension, typename TPixelType>
void MyClass::DoAnotherThing() 
{
    static_assert(Dimension > 2, "function not available!" );
    // ...
}

在C 2a中,您可以使用requires进行"丢弃"方法:

template<int Dimension, typename TPixelType = float>
class MyClass
{
    void DoSomething();
    void DoAnotherThing() requires (Dimension > 2);
};

一般建议:如果您有模板类,请在标题中实现全部并避免CPP文件。所有这些都变得简单得多。

如果模板参数不符合标准(某些值或类型(,我可以防止模板类的函数的产生吗?这可以通过使用C 代码和无预处理器指令来实现吗?

是,是的:搜索Sfinae。

在您的情况下(C 11和更新(

template <int Dimension, typename TPixelType = float>
class MyClass
 {
   public:
      void DoSomething ()
       { }
      template <int D = Dimension,
                typename std::enable_if<(D > 2), bool>::type = true>
      void DoAnotherThing()
       { }
 };

现在仅在 D > 2 D(默认情况下(等于 Dimension时,才实现 DoAnotherThing()方法。

不是一个完美的解决方案,因为可以"被劫持"阐明D

的值
auto myclass0 = MyClass<2>();
myclass0.DoAnotherThing<5>(); // compile because D is 5

但是您可以防止此问题添加D等于Dimension

的测试
  template <int D = Dimension, // ..VVVVVVVVVVVVVVVV
            typename std::enable_if<(D == Dimension)
                                 && (D > 2), bool>::type = true>
  void DoAnotherThing()
   { }

so

auto myclass0 = MyClass<2>();
myclass0.DoAnotherThing<5>(); // doesn't compile anymore because 5 != 2