簡體   English   中英

可變參數模板和std :: function

[英]variadic template and std::function

在下面的代碼中:

#include <functional>
#include <iostream>
#include <tuple>

template <typename... t>
class a {
 public:
  explicit a(std::function<std::tuple<t...>()>&& p_d,
             std::function<bool(t...)>&& p_f)
      : m_d(std::move(p_d)), m_f(std::move(p_f)) {}

  bool operator()() { return m_f(m_d()); }

 private:
  std::function<std::tuple<t...>()> m_d;
  std::function<bool(t...)> m_f;
};

class d {
  std::tuple<int, float, std::string&&> operator()() {
    return std::tuple<int, float, std::string&&>(-9, 3.14, "olá!");
  }
};

class f {
  bool operator()(int p_i, float p_f, std::string&& p_s) {
    std::cout << "i = " << p_i << ", f = " << p_f << ", s = " << p_s
              << std::endl;
    return true;
  }
};

int main() {
  d _d;
  f _f;
  typedef a<int, float, std::string&&> a_t;

  a_t _a(std::move(_d), std::move(_f));

  _a();

  return 0;
}

我收到編譯器錯誤:

../untitled014/main.cpp: In function ‘int main()’:
../untitled014/main.cpp:38:38: error: no matching function for call to ‘a<int, float, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&>::a(std::remove_reference<d&>::type, std::remove_reference<f&>::type)’
   a_t _a(std::move(_d), std::move(_f));
                                      ^
../untitled014/main.cpp:8:12: note: candidate: a<t>::a(std::function<std::tuple<_Elements ...>()>&&, std::function<bool(t ...)>&&) [with t = {int, float, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&}]
   explicit a(std::function<std::tuple<t...>()>&& p_d,
            ^
../untitled014/main.cpp:8:12: note:   no known conversion for argument 1 from ‘std::remove_reference<d&>::type {aka d}’ to ‘std::function<std::tuple<int, float, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&>()>&&’

我不明白為什么編譯器找不到合適的轉換,因為它在錯誤的最后一行中報告。

我正在Xubuntu框上使用帶有標志'-std = c ++ 14'的g ++,並且'g ++ --version'報告'g ++(Ubuntu 5.4.0-6ubuntu1〜16.04.10)5.4.0 20160609'

誰能告訴我我在做什么錯?

謝謝!!

我在您的代碼中看到至少三個錯誤。

沒有特別的順序...

(1)如果您想要功能, operator()必須是public 你讓他們都private

class d { // default for a class is private, so operator() is private
  std::tuple<int, float, std::string&&> operator()() {
    return std::tuple<int, float, std::string&&>(-9, 3.14, "olá!");
  }
};

class f { // default per a class is private, so operator() is private
  bool operator()(int p_i, float p_f, std::string&& p_s) {
    std::cout << "i = " << p_i << ", f = " << p_f << ", s = " << p_s
              << std::endl;
    return true;
  }
};

您可以解決此問題,使operator() public ,或者使df struct更簡單。

(2) "olá!" 不是初始化std::string &&的有效值

 std::tuple<int, float, std::string&&>(-9, 3.14, "olá!");

你可以用

 std::tuple<int, float, std::string&&>(-9, 3.14, std::string{"olá!"});

但這是一個錯誤的主意,因為用這種方式,您用一個對象的引用初始化了一個對象,該對象在此之后立即被銷毀,並且在元組中獲得了一個懸空的引用。

我不清楚,為什么要在元組中使用std::string && ,但我懷疑您可以使用std::string ,而不是對其的引用。 在所有代碼中,不僅限於此功能。

在這種情況下,以下代碼

std::tuple<int, float, std::string>(-9, 3.14, "olá!");

作品。

如果您確實要在元組中引用std::string ,則必須將引用傳遞給對象,該對象的生存期應足以覆蓋元組的生存期。

(3) doperator()返回std::tuple<int, float, std::string&&> ,其中foperator()接受三個參數: intfloatstd::string&&

因此,您不能簡單地將第一個返回的值傳遞給第二個,而不用像打開a::operator()那樣解壓std::tuple

bool operator()() { return m_f(m_d()); }
// ........................^^^^^^^^^^  Wrong!

您正在使用C ++ 14,因此無法使用std::apply() (可從C ++ 17開始使用)

bool operator()() { return std::apply(m_f, m_d()); }
// ........................^^^^^^^^^^^^^^^^^^^^^^  Starting from C++17

因此您必須以某種方式進行仿真( std::make_index_sequencestd::index_sequencestd::get()等)。

舉個例子

  bool operator() ()
   { return call(std::make_index_sequence<sizeof...(t)>{}); }

  template <std::size_t ... Is>
  auto call (std::index_sequence<Is...> const &)
   {
     auto tmp { m_d() }; // so m_d() is called only one time

     return m_f(static_cast<t>(std::get<Is>(tmp))...);
   }

其中call()可以是private

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM