C++ 根据C+;中的变量参数,具有尾部返回类型的泛型lambda+;11
在C++14中,可以执行以下操作:C++ 根据C+;中的变量参数,具有尾部返回类型的泛型lambda+;11,c++,c++11,lambda,c++14,C++,C++11,Lambda,C++14,在C++14中,可以执行以下操作: struct Placeholder { template<typename T> constexpr static T fct(T val) { return val; } }; int main() { constexpr int i{}; auto fct = [](auto&& placeholder) -> decltype(placeholder.fct(i)) { return
struct Placeholder
{
template<typename T>
constexpr static T fct(T val) { return val; }
};
int main()
{
constexpr int i{};
auto fct = [](auto&& placeholder) -> decltype(placeholder.fct(i)) { return 5.5f; };
static_assert(fct(Placeholder{}) == 5, "");
}
然而,在C++11中,由于我们不能在一个类中存储可变数量的成员,我不知道如何才能获得完全相同的结果。有什么想法吗?据我所知,可以从@RichardHodges的想法中得出一个纯C++11解决方案。您需要手动重新编码
std::apply
。为此,您还需要重新编码std::integer\u sequence
,std::index\u sequence
和std::make\u index\u sequence
。让我们从这个开始:
template <typename T, T... Is>
struct integral_sequence {};
template <std::size_t... Is>
using index_sequence = integral_sequence<std::size_t, Is...>;
template <typename Seq, typename T, T... el>
struct append_sequence;
template <typename T, T... el, T... Is>
struct append_sequence<integral_sequence<T, Is...>, T, el...> {
using type = integral_sequence<T, Is..., el...>;
};
namespace details {
template <std::size_t N>
struct make_index_sequence_impl {
private:
using seq = typename make_index_sequence_impl<N-1>::type;
public:
using type = typename append_sequence<seq, std::size_t, N>::type;
};
template <>
struct make_index_sequence_impl<0u> {
using type = index_sequence<0>;
};
template <std::size_t N>
struct make_index_sequence {
using type = typename make_index_sequence_impl<N-1>::type;
};
template <>
struct make_index_sequence<0u> {
using type = index_sequence<>;
};
} // namespace details
template <std::size_t N>
using make_index_sequence = typename details::make_index_sequence<N>::type;
然后,暴露的apply
进入:
template <typename F, typename Tuple>
template <typename F, typename Tuple>
auto apply(F&& ftor, Tuple&& tuple) -> decltype(details::apply_impl(std::forward<F>(ftor), std::forward<Tuple>(tuple), make_index_sequence<std::tuple_size<typename std::remove_reference<Tuple>::type>::value>())){
return details::apply_impl(std::forward<F>(ftor), std::forward<Tuple>(tuple), make_index_sequence<std::tuple_size<typename std::remove_reference<Tuple>::type>::value>());
}
根据我的理解,一个纯粹的C++11解决方案可以从@RichardHodges的想法中得到。您需要手动重新编码
std::apply
。为此,您还需要重新编码std::integer\u sequence
,std::index\u sequence
和std::make\u index\u sequence
。让我们从这个开始:
template <typename T, T... Is>
struct integral_sequence {};
template <std::size_t... Is>
using index_sequence = integral_sequence<std::size_t, Is...>;
template <typename Seq, typename T, T... el>
struct append_sequence;
template <typename T, T... el, T... Is>
struct append_sequence<integral_sequence<T, Is...>, T, el...> {
using type = integral_sequence<T, Is..., el...>;
};
namespace details {
template <std::size_t N>
struct make_index_sequence_impl {
private:
using seq = typename make_index_sequence_impl<N-1>::type;
public:
using type = typename append_sequence<seq, std::size_t, N>::type;
};
template <>
struct make_index_sequence_impl<0u> {
using type = index_sequence<0>;
};
template <std::size_t N>
struct make_index_sequence {
using type = typename make_index_sequence_impl<N-1>::type;
};
template <>
struct make_index_sequence<0u> {
using type = index_sequence<>;
};
} // namespace details
template <std::size_t N>
using make_index_sequence = typename details::make_index_sequence<N>::type;
然后,暴露的apply
进入:
template <typename F, typename Tuple>
template <typename F, typename Tuple>
auto apply(F&& ftor, Tuple&& tuple) -> decltype(details::apply_impl(std::forward<F>(ftor), std::forward<Tuple>(tuple), make_index_sequence<std::tuple_size<typename std::remove_reference<Tuple>::type>::value>())){
return details::apply_impl(std::forward<F>(ftor), std::forward<Tuple>(tuple), make_index_sequence<std::tuple_size<typename std::remove_reference<Tuple>::type>::value>());
}
结合一些例子,我不认为。。。理解你的问题是什么。你到底想做什么?您最初的C++14示例和C++11示例不等效,因此我无法推断问题所在。它们为什么不等效?在C++11中,我看不到任何其他方法可以达到相同的结果……至于我的用法,我使用lambda和SFINAE来检测constexpr输入(lambda显然没有使用)。它在C++14中运行良好,但我正在尝试使其与C++11兼容。有关类似的用例,请参见。lambda示例没有捕获任何内容。在
函子
示例(实际上不是a)中,它有一个成员变量。无论如何,如果它有一个清晰的问题陈述,说明你在C++14中可以做什么,但在C++11中却在挣扎,那么它会对你的问题有很大帮助。用std::tuple
替换T
。在c++11等价于std::index_序列的帮助下,将元组解压到参数列表中。。。理解你的问题是什么。你到底想做什么?您最初的C++14示例和C++11示例不等效,因此我无法推断问题所在。它们为什么不等效?在C++11中,我看不到任何其他方法可以达到相同的结果……至于我的用法,我使用lambda和SFINAE来检测constexpr输入(lambda显然没有使用)。它在C++14中运行良好,但我正在尝试使其与C++11兼容。有关类似的用例,请参见。lambda示例没有捕获任何内容。在函子
示例(实际上不是a)中,它有一个成员变量。无论如何,如果它有一个清晰的问题陈述,说明你在C++14中可以做什么,但在C++11中却在挣扎,那么它会对你的问题有很大帮助。用std::tuple
替换T
。借助与std::index_sequence
等效的c++11将元组解压到参数列表中,另请参见我对std::apply()
的c++14实现的回答。另请参见我对std::apply()
的c++14实现的回答。
namespace details {
template <typename F, typename Tuple, std::size_t... Is>
auto apply_impl(F&& ftor, Tuple&& tuple, index_sequence<Is...>) -> decltype(std::forward<F>(ftor)(std::get<Is>(tuple)...)) {
return std::forward<F>(ftor)(std::get<Is>(tuple)...);
}
} // namespace details
template <typename F, typename Tuple>
template <typename F, typename Tuple>
auto apply(F&& ftor, Tuple&& tuple) -> decltype(details::apply_impl(std::forward<F>(ftor), std::forward<Tuple>(tuple), make_index_sequence<std::tuple_size<typename std::remove_reference<Tuple>::type>::value>())){
return details::apply_impl(std::forward<F>(ftor), std::forward<Tuple>(tuple), make_index_sequence<std::tuple_size<typename std::remove_reference<Tuple>::type>::value>());
}
template <typename... Ts>
class Functor {
std::tuple<Ts...> is;
public:
constexpr Functor(Ts... ts) : is(std::make_tuple(ts...)) {}
template <typename P>
constexpr auto operator()(P&& placeholder) -> decltype(apply(std::forward<P>(placeholder), is)) {
return apply(std::forward<P>(placeholder), is);
}
};