根据维度启用一个operator()

时间:2017-03-24 14:13:54

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

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

因此,如果表单维度为n,则运算符应具有n整数参数,因此formdim == 1的线性表单应为operator()(i)formdim == 2operator()(i, j)我想要enable_if

我认为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; } }; 可以提供任何帮助,但我对TMP并不是非常认真,而且我有编译错误:

 CASE WHEN @Site = 'PEnnsylvania' AND A.so_prod_key LIKE '110%' 
THEN A.so_prod_key ELSE NULL END As col1

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

感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

在C ++ 17中,您可以使用if constexpr(即static 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

答案 1 :(得分: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);
}