3

このかなり不自然な例では、関数テンプレートを関数に渡そうとしており、関数に関数テンプレートを内部でインスタンス化させたいと考えています。本質的には、ユーザーに関数のタイプと動作を知られたくないのですが、関数テンプレートを渡して自分自身をインスタンス化することができます。自己完結型の例(コンパイルされません):

#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>

template <template <typename InputIt, typename OutputIt> class CopyFunc>
void transferWith( CopyFunc<std::vector<int>::const_iterator,
                            std::back_insert_iterator<std::vector<int>>> const& func )
{
    std::vector<int> source{1, 2, 3, 4, 5, 6, 7};
    std::vector<int> sink;

    func(source.begin(), source.end(), std::back_inserter(sink));

    for (auto&& e : sink)
    {
        std::cout << e << std::endl;
    }
}

int main(int argc, char const *argv[])
{

    // I want to pass just the function template in,
    // and instantiate it internally
    transferWith(std::copy);

    return 0;
}

これは、gcc-4.7.2で期待どおりにコンパイルできず、次のエラーが発生します。

main.cpp|25 col 27 error| no matching function for call to ‘transferWith(<unresolved overloaded function type>)’
main.cpp|8 col 6 error| note: template<template<class InputIt, class OutputIt> class CopyFunc> void transferWith(const CopyFunc<__gnu_cxx::__normal_iterator<const int*, std::vector<int> >, std::back_insert_iterator<std::vector<int> > >&)
main.cpp|25 col 27 error| note:   couldn't deduce template parameter ‘template<class InputIt, class OutputIt> class CopyFunc’

これを回避するために引っ張ることができるトリックや間接的なものはありますか?

ありがとうございました。

4

3 に答える 3

2

完全を期すために、ファンクターアプローチの例を次に示します。

#include <algorithm>
#include <vector>
#include <iostream>

struct Copy {
  template <typename InputIter, typename OutputIter>
  OutputIter operator()(InputIter i1, InputIter i2, OutputIter o1) {
    return std::copy(i1, i2, o1);
  }
};

template <typename CopyFunctor> 
void foo(CopyFunctor cf) {
  std::vector<int> v1 = {3, 1, 4}; 
  std::vector<int> v2(v1.size());

  cf(v1.begin(), v1.end(), v2.begin());

  for (auto i : v2) {
    std::cout << i << ' ';
  }
}

int main() {
  foo(Copy());  // displays "3 1 4"
}
于 2013-01-02T19:53:46.707 に答える
2

これを回避するために引っ張ることができるトリックや間接的なものはありますか?

はい。テンプレートを使用してファンクターオブジェクトを渡しますoperator()()

コードは、 Bartの回答のバージョンとまったく同じようになります。

于 2013-01-02T19:24:39.263 に答える
0

線に沿って何かしますか

template <template <typename InputIt, typename OutputIt> class CopyFunc> void transferWith()
{
    std::vector<int> source{1, 2, 3, 4, 5, 6, 7};
    std::vector<int> sink;

    CopyFunc<std::vector<int>::const_iterator, std::vector<int>::iterator>(source.begin(), source.end(), std::back_inserter(sink));

    for (auto&& e : sink)
    {
        std::cout << e << std::endl;
    }
}

と呼ばれる:

transferWith<std::copy>();

行う?

私はこれが箱から出してコンパイルされることを約束していません...

于 2013-01-02T18:58:44.347 に答える