C++ 根据C+;中的变量参数,具有尾部返回类型的泛型lambda+;11

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

在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 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);
    }
};