【问题标题】:Enable one operator() based on the dimension根据维度启用一个operator()
【发布时间】:2017-03-24 14:13:53
【问题描述】:

我想创建一个form 类,该类基于其模板参数,为一个operator() 提供一个或多个参数。这是曲线的原型,例如线性、双线性等。

所以,如果表单维度是n,则运算符应该有n 整数参数,所以带有formdim == 1 的线性表单应该有operator()(i)formdim == 2 我想要operator()(i, j)

我认为enable_if 可能会有所帮助,但我对 TMP 并没有深入了解,而且我有一个编译错误:

template<unsigned int formdim>
class form
{
public:
    form()
    {}

    auto operator()(unsigned int j) -> typename std::enable_if<formdim == 1, unsigned int>::type
    {
        std::cout << "LINEAR" << std::endl;
        return 0;
    }

    // Here I get a compiler error due to the missing type
    auto operator()(unsigned int i, unsigned int j) -> typename std::enable_if<formdim == 2, double>::type
    {
        std::cout << "BILINEAR" << std::endl;
    }
};

我怎样才能提供这样的课程?我不需要参数的数量是自动,我可以根据需要手动添加新的运算符...但显然它确实非常酷。

感谢您的帮助!

【问题讨论】:

    标签: c++ c++11 templates operator-overloading


    【解决方案1】:

    在 C++17 中,您可以使用 if constexpr(即静态 if 子句)并将其执行为:

    template<unsigned int formdim>
    class form {
    public:
        template<typename... Args>
        decltype(auto) operator()(Args&&... args) {
          if constexpr (formdim == 1) {
            static_assert(sizeof...(args) == 1);
           std::cout << "LINEAR" << std::endl;
           return 0;
          } else if constexpr (formdim == 2) {
           static_assert(sizeof...(args) == 2);
           std::cout << "BILINEAR" << std::endl;
           return 0.0;
          } else {
            static_assert(sizeof...(args) < 3);
            return 0;
          }
        }
    };
    

    Live Demo

    【讨论】:

      【解决方案2】:

      enable_if 必须直接依赖于您声明的模板参数。在您的情况下,您依赖于类的模板参数,而不是您声明的方法。将模板参数添加到您的方法中,并为其提供类模板参数的值。试试这个:

      #include <iostream>
      #include <type_traits>
      
      template<unsigned int formdim>
      class form
      {
      public:
          form()
          {}
      
          // Use T instead of formdim in enable_if
          template<unsigned int T = formdim>
          auto operator()(unsigned int j) -> typename std::enable_if<T == 1, unsigned int>::type
          {
              std::cout << "LINEAR" << std::endl;
              return 0;
          }
      
          // Use T instead of formdim in enable_if
          template<unsigned int T = formdim>
          auto operator()(unsigned int i, unsigned int j) -> typename std::enable_if<T == 2, double>::type
          {
              std::cout << "BILINEAR" << std::endl;
              return 0;
          }
      };
      
      int main()
      {
      
          form<1> x;
          form<2> y;
          x(42);
          y(42, 43);
      }
      

      【讨论】:

        猜你喜欢
        • 2021-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多