模板参数简化

时间:2014-06-27 09:39:12

标签: c++ templates

我是C ++的新手(使用C ++ 2011),我想找到解决以下问题的方法。我有一个代表一个功能的课程:

class Curve {
private:
    ...
public:
    std::array<double, 3> value(double s);
}

我正在使用该对象将此函数传递给由类表示的算法:

template <int n, typename Functor>
class Algorithm {
private:
    Functor f;
    std::array<double, n> a;
public:
    ...
}

然后我创建了对象

Algorithm<3, Curve> solver;

但是3显然是来自任何类型Curve的方法值返回的数组大小的3。我想简化这段代码,以便我可以使用:

Algorithm<Curve> solver;

但我不知道如何做到这一点。你介意给我一个暗示吗?

祝你好运, 弗朗索瓦

3 个答案:

答案 0 :(得分:8)

添加成员array_length或类似Curve类的内容:

class Curve
{
public:
    static constexpr const std::size_t length = 3;

private:
    std::array<double,length> a;
};

template<typename ALGORITHM , std::size_t n = ALGORITHM::length>
class Algorithm
{
    ...
};

如果您需要允许经典函数实体作为算法,那么该方法不起作用,因为没有length成员。其他方法可能是创建元函数data_length 给定算法函数F的函数返回数据的长度:

template<typename F>
struct length;

//Specialization for Curve class:
template<>
struct length<Curve> : public std::integral_constant<std::size_t,3>
{};

然后:

template<typename F , std::size_t n = length<F>::value>
struct Algorithm
{
   ...
};

编辑:与其他任何模板一样,要实现该方法,请指定其模板参数:

template<typename F , std::size_t N>
void Algorithm<F,N>::execute()
{
    _f();
}

Here是一个正在运行的例子。

答案 1 :(得分:1)

你可以&#34;通过&#34;像这样的枚举成员中的3:

class Curve {
public:
   enum { arity = 3 };
   std::array<double, arity> value(double s);
};

template <typename Functor>
class Algorithm {
private:
   std::array<double, Functor::arity> a;
};

Curve curve;
Algorithm<Curve> solver;

答案 2 :(得分:1)

使用decltype获取value的返回类型,并使用std::tuple_size查看其大小(Live at Coliru):

template <typename Functor>
class Algorithm {
private:
    Functor f;
    static const std::size_t n =
      std::tuple_size<decltype(f.value(0.))>::value;
    std::array<double, n> a;
public:
    // ...
};

or if you simply want a to have the same type that value returns

template <typename Functor>
class Algorithm {
private:
    Functor f;
    decltype(f.value(0.)) a;
public:
    // ...
};

或者如果有一天你想使用其他类型的功能 - 比如intlong long或其他什么 - you can ask for the return type of f.value when invoked with a default-constructed value of whatever its argument type happens to be

template <typename Functor>
class Algorithm {
private:
    Functor f;
    decltype(f.value({})) a;
public:
    // ...
};