在以下代码中:
#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'
有人可以告诉我我在做什么错吗?
谢谢!
答案 0 :(得分:0)
我在您的代码中至少看到三个错误。
没有特殊顺序...
(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()
的{{1}}或更简单地制作public
和d
f
的问题。
(2)struct
不是初始化"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á!");
,则必须将引用传递给对象,该对象的寿命应足以覆盖元组的寿命。
(3)std::string
的{{1}}返回一个operator()
,其中d
的{{1}}接受三个参数:a std::tuple<int, float, std::string&&>
,a operator()
和f
。
因此,就像在int
中一样,您不能简单地将第一个返回的值传递给第二个,而不用解包float
std::string&&
您正在使用C ++ 14,所以不能使用std::tuple
(从C ++ 17开始可用)
a::operator()
所以您必须以某种方式进行仿真(bool operator()() { return m_f(m_d()); }
// ........................^^^^^^^^^^ Wrong!
,std::apply()
,bool operator()() { return std::apply(m_f, m_d()); }
// ........................^^^^^^^^^^^^^^^^^^^^^^ Starting from C++17
等)。
通过示例
std::make_index_sequence
其中std::index_sequence
可以是std::get()