标签: stdapply

使用std :: apply和variadic包

我正在尝试创建一个泛型类,它接受一组类型,将它们存储在元组中,并可以对它们应用函数.

到目前为止我尝试的是以下内容:

#include <tuple>
struct Base{
    virtual void base_function() = 0;
};

template<typename ...T>
struct A : public Base{
    std::tuple<T...> as;
    A(T... pack):as(pack...){};
    void base_function(){
        std::apply([](auto t){t.base_function();}, as);
    }
};

struct B : public Base{
    void base_function(){};
};


struct C : public Base{
    void base_function(){};
};

struct D : A<B, C>{
    D():A(B(),C()){};
};
Run Code Online (Sandbox Code Playgroud)

我期望在D上调用base_function时从类B和C调用base_function但是编译器会生成以下错误:

错误:没有匹配函数来调用
' __invoke(A<T>::base_function() [with T = {B, C}]::<lambda(auto:1)>, std::__tuple_element_t<0, std::tuple<B, C> >&, std::__tuple_element_t<1, std::tuple<B, C> >&)'

c++ templates c++17 stdapply

10
推荐指数
1
解决办法
676
查看次数

std :: apply和constant表达式?

我在Wandbox中尝试了以下代码:

#include <array>
#include <iostream>
#include <tuple>
#include <typeinfo>
#include <functional>
#include <utility>


int main()
{
    constexpr std::array<const char, 10> str{"123456789"};
    constexpr auto foo = std::apply([](auto... args) constexpr { std::integer_sequence<char, args...>{}; } , str);
    std::cout << typeid(foo).name();
}
Run Code Online (Sandbox Code Playgroud)

并且编译器告诉我那args...不是常量表达式.怎么了?

c++ c++17 stdapply

9
推荐指数
3
解决办法
592
查看次数

std ::如何在没有显式std :: forward的情况下应用转发参数?

考虑可能的实施std::apply:

namespace detail {
template <class F, class Tuple, std::size_t... I>
constexpr decltype(auto) apply_impl(F &&f, Tuple &&t, std::index_sequence<I...>) 
{
    return std::invoke(std::forward<F>(f), std::get<I>(std::forward<Tuple>(t))...);
}
}  // namespace detail

template <class F, class Tuple>
constexpr decltype(auto) apply(F &&f, Tuple &&t) 
{
    return detail::apply_impl(
        std::forward<F>(f), std::forward<Tuple>(t),
        std::make_index_sequence<std::tuple_size_v<std::decay_t<Tuple>>>{});
}
Run Code Online (Sandbox Code Playgroud)

为什么在调用f带有参数元组的function()来传递(t)时,我们不需要在实现std::forward中对元组的每个元素std::get<I>(std::forward<Tuple>(t))...执行?

c++ perfect-forwarding c++17 stdapply

9
推荐指数
1
解决办法
342
查看次数

无法对用户定义类型使用 std::apply

在为我正在从事的某个项目实现一个compressed_tuple类时,我遇到了以下问题:我似乎无法将这种类型的实例传递给 std::apply,尽管根据以下内容这应该是可能的:https:// en.cppreference.com/w/cpp/utility/apply

我使用以下片段(godbolt)很容易地重现了这个问题:

#include <tuple>

struct Foo {
public:
    explicit Foo(int a) : a{ a } {}

    auto &get_a() const { return a; }
    auto &get_a() { return a; }

private:
    int a;
};

namespace std {

template<>
struct tuple_size<Foo> {
    constexpr static auto value = 1;
};

template<>
struct tuple_element<0, Foo> {
    using type = int;
};

template<size_t I>
constexpr auto get(Foo &t) -> int & {
    return t.get_a();
}

template<size_t I> …
Run Code Online (Sandbox Code Playgroud)

c++ tuples c++17 stdapply

5
推荐指数
1
解决办法
568
查看次数

使用std :: apply应用可变参数函数

是否可以使用std :: apply将可变参数函数应用于元组?

例如,以下代码适用于GCC 6.2.1:

void print_t(std::string i, std::string j) {
    std::cout << i << " " << j << std::endl;
}

int main() {
        std::tuple<std::string, std::string> t{"ab", "cd"};
        std::experimental::apply(print_t, t);
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我尝试应用可变参数函数:

template<typename T>
void vprint(T && t) {
    std::cout << std::forward<T>(t) << std::endl;
}

template<typename T, typename ... Ts>
void vprint(T && t, Ts ... ts) {
    std::cout << std::forward<T>(t) << " ";
    vprint<Ts...>(std::forward<Ts>(ts)...);
}

int main() {
        std::tuple<std::string, std::string> t{"fd", "ab"};
        std::experimental::apply(vprint, t);
        return 0; …
Run Code Online (Sandbox Code Playgroud)

c++ apply c++14 c++17 stdapply

4
推荐指数
1
解决办法
1988
查看次数

std::apply 应该只适用于 std::tuple 吗?

的函数签名std::apply不会将模板参数限制Tuple为 的特化std::tuple,因此它仍然可以接受定义(godbolt)的类似元组的对象:std::tuple_size_v

#include <tuple>
#include <utility>
#include <array>

int main() {
  std::apply([](int, int) {}, std::array{0, 0});
  std::apply([](int, int) {}, std::pair {0, 0});
  std::apply([](int, int) {}, std::tuple{0, 0});
}
Run Code Online (Sandbox Code Playgroud)

但[tuple.apply]std::apply中的描述是:

tuple20.5.5 使用参数调用函数

这是否意味着应用于std::apply除此之外的对象std::tuple是未定义的行为?

c++ language-lawyer stdtuple c++17 stdapply

3
推荐指数
1
解决办法
303
查看次数

在类方法上使用 std::apply

我试图编译以下内容(g++-11.2,C++20),但我得到:

error: no matching function for call to '__invoke(std::_Mem_fn<void (Foo::*)(int, double)>, std::__tuple_element_t<0, std::tuple<int, double> >, std::__tuple_element_t<1, std::tuple<int, double> >)'
 1843 |       return std::__invoke(std::forward<_Fn>(__f),
Run Code Online (Sandbox Code Playgroud)

代码:

#include <iostream>
#include <tuple>

struct Foo
{
    void bar(const int x, const double y) 
    {  
        std::cout << x << " " << y << std::endl;
    }  


    void bar_apply()
    {  
        // fails
        std::apply(std::mem_fn(&Foo::bar), std::tuple<int, double>(1, 5.0));
    }  
};


int main()
{
    Foo foo;
    foo.bar_apply();
};
Run Code Online (Sandbox Code Playgroud)

c++ tuples c++17 c++20 stdapply

3
推荐指数
1
解决办法
1333
查看次数

std::visit 带有重载自由函数而不是函数对象的 std::variant

在 C++17 中,是否有一种简单的方法来 std::visit 带有重载自由函数的变体,或者我必须使用带有重载调用运算符的对象?

换句话说,是否可以添加一些简单的东西来使以下//ERROR!行编译为与该//OK!行在功能上相同?

#include<variant>
#include<iostream>
#include<list>

#include <boost/hana/functional/overload.hpp>
using boost::hana::overload;

struct A {};
struct B {};

void foo(A) { std::cout << "Got an A!\n"; }
void foo(B) { std::cout << "Got a  B!\n"; }

using AorB = std::variant<A,B>;

constexpr auto foo_obj = overload(
    [](A){std::cout << "Got an A!\n";},
    [](B){std::cout << "Got a  B!\n";});

int main() {

  std::list<AorB> list{A(), B(), A(), A(), B()};

  for (auto& each : list) std::visit(foo, each);      // ERROR!
  for (auto& …
Run Code Online (Sandbox Code Playgroud)

c++ non-member-functions c++17 stdapply std-variant

2
推荐指数
1
解决办法
846
查看次数

std::function 与可作为模板参数调用

在下面的示例中,为什么第 20 行会导致第 27 行到第 30 行描述的错误?

在第 33 行调用exec1效果很好。

#include <cstdint>
#include <functional>
#include <iostream>
#include <tuple>
#include <type_traits>

template <typename... t_fields>
void exec0(std::function<std::tuple<t_fields...>()> generate,
           std::function<void(t_fields &&...)> handle) {
  std::tuple<t_fields...> _tuple{generate()};
  std::apply(handle, std::move(_tuple));
}

template <typename t_generate, typename t_function>
void exec1(t_generate generate, t_function handle) {
  auto _tuple{generate()};
  std::apply(handle, std::move(_tuple));
}

int main() {
  auto _h = [](uint32_t u) -> void { std::cout << "u = " << u << '\n'; };

  auto _g = []() -> std::tuple<uint32_t> …
Run Code Online (Sandbox Code Playgroud)

c++ variadic-templates std-function template-argument-deduction stdapply

1
推荐指数
1
解决办法
392
查看次数