当我知道类型名时,嵌套模板参数

时间:2016-11-14 10:35:32

标签: c++ templates

在这种情况下,我有一个Algorithm类:

template <typename SourceType, typename DestType>
class Algorithm {
  bool apply() { ... return true;}
};

我正在尝试创建一个Helper来抽象用户完全定义Algorithm类。这是我对实现的想法:

template <typename DataType, template <typename, typename> class AlgorithmType>
bool Helper(const DataType* soure, DataType* dest) {
  AlgorithmType<DataType, DataType> alg;
  return alg.apply();
}

Helper功能是否正确?有没有更好的方法呢?

3 个答案:

答案 0 :(得分:3)

看起来确实如此。但是你的apply不会返回任何内容,即UB。

至于改进,你可以颠倒模板参数的顺序,并推导出DataType

template <template <typename, typename> class AlgorithmType, typename DataType>
bool Helper(const DataType* soure, DataType* dest) {
  AlgorithmType<DataType, DataType> alg;
  return alg.apply();
}

现在你可以用

来调用它
Helper<Algorithm>(const_ptr, ptr);

您可以阻止对第二个参数的推论,使其更加健壮:

template<typename T> struct identity{ using type = T; };
template<typename T>
using block_deduction = typename identity<T>::type;

template <template <typename, typename> class AlgorithmType, typename DataType>
bool Helper(const DataType* soure, block_deduction<DataType*> dest) {
  AlgorithmType<DataType, DataType> alg;
  return alg.apply();
}

现在你可以用

来调用它
Helper<Algorithm>(const_ptr, const_ptr);

答案 1 :(得分:3)

Helper函数是正确的,但您可能希望将typename DataType作为最后一个模板参数,以便可以从函数调用中推导出来:

template <template <typename, typename> class AlgorithmType, typename DataType>
bool Helper(const DataType* soure, DataType* dest) {
  AlgorithmType<DataType, DataType> alg;
  return alg.apply();
}

现在您可以使用Helper,如下所示:

int main()
{
    const int* some_src_ptr = /*...*/;
    int* some_dst_ptr = /*...*/;
    Helper<SomeAlgorithmTemplate>(some_src_ptr, some_dst_ptr);
}

或者,您可以将整个算法作为模板参数传递,让用户处理选择SourceTypeDestType

template <typename SourceType, typename DestType>
class Algorithm {
public:
  using source_type = SourceType;
  using dest_type = DestType;
private:
  bool apply() {}
};

template <typename Algo>
bool Helper(const typename Algo::source_type* soure, typename Algo::dest_type* dest) {
  Algo alg;
  return alg.apply();
}

现在您可以使用Helper,如下所示:

int main()
{
    const int* some_src_ptr = /*...*/;
    int* some_dst_ptr = /*...*/;
    Helper<SomeAlgorithmTemplate<int, int>>(some_src_ptr, some_dst_ptr);
}

答案 2 :(得分:2)

您也可以考虑使算法独立于编译时参数,并使用例如像这样的东西:

struct Algorithm {
   template <class Source, class Dest>
   bool operator()(Source source, Dest dest) {
       //...
       return something;
   }
};

然后:

template <class AlgType, typename DataType>
bool Helper(const DataType* soure, DataType* dest) {
  AlgType alg;
  return alg(source, dest);
}

运行:

Helper<Algorithm>(source_ptr, dest_ptr);