在具有约束的可变参数类模板构造函数中转发参数

Forwarding arguments in a variadic class template constructor with constraints

提问人:SKNB 提问时间:11/13/2023 最后编辑:SKNB 更新时间:11/13/2023 访问量:97

问:

给定一个带有可变参数的类模板,以及参数必须具有的约束

  1. 某种类型,以及
  2. 特定顺序

在构造函数中,如何将可变数量的 r 值引用 () 转发到成员引用(对应于可变参数的类型)?&&tuple

我的尝试都导致了错误:

(叮当):non-const lvalue reference to type 'tuple<...>' cannot bind to a temporary of type 'tuple<...>'

戈德博尔特https://godbolt.org/z/YPWcjGWf3

Template.hpp

#include <concepts>
#include <tuple>
#include <type_traits>
#include <utility>

// Functor class
template<typename X, typename Y = X>
struct Functor
{
    using first  = X;
    using second = Y;

    Functor(X lVal) :
        x(lVal)
    {
    }

    X x;
};

// traits/concept
template<typename...>
struct is_Functor : std::false_type
{
};

template<typename X, typename Y>
struct is_Functor<Functor<X, Y>> : std::true_type
{
};

template<typename T>
inline constexpr bool is_Functor_v = is_Functor<T>::value;

template<typename T>
concept FunctorConcept = is_Functor_v<T>;

// template
template<typename Start, typename End, typename... Functors>
    requires requires(Functors... fs) {
                 []<typename... X, typename... Y>(Functor<X, Y> & ...)
                     requires std::same_as<void(Start, Y...), void(X..., End)>
                 {
                 }
                 (fs...);
             }
class Template
{
public:
    using start_type     = Start;
    using end_type       = End;
    using functors_tuple = std::tuple<Functors...>;
    using size_type      = std::size_t;

    template<typename... _Functors>
        requires(std::convertible_to<std::tuple<_Functors...>, functors_tuple>)
    Template(_Functors&&... fs) :
        m_functors(functors_tuple(fs)...) {};

private:
    functors_tuple& m_functors;
};

template<typename _first, typename _last>
class Template<typename _first::first, typename _last::second, _first, _last>
{
};

template<typename _Functor>
    requires FunctorConcept<_Functor>
class Template<typename _Functor::first, typename _Functor::second, _Functor>
{
};

template<typename I, typename O>
class Template<I, O, Functor<I, O>>
{
};

#include <iostream>
#include <string>

template<typename A, typename B>
struct SomeFunctor : public Functor<A, B>
{
    SomeFunctor(A a) :
        Functor<A, B>(a) {};

    B operator()(B b)
    {
        return this->x * b;
    }
};

main.cpp

#include <iostream>
#include <string>

template<typename A, typename B>
struct SomeFunctor : public Functor<A, B>
{
    SomeFunctor(A a) :
        Functor<A, B>(a) {};

    B operator()(B b)
    {
        return this->x * b;
    }
};

int main(int argc, char** argv)
{
    SomeFunctor<short, int>      f1(8);
    SomeFunctor<int, long>       f2(11);
    SomeFunctor<long, long long> f3(-2);

    Template<short, long long, SomeFunctor<short, int>, SomeFunctor<int, long>, SomeFunctor<long, long long>> t(f1, f2, f3);

#ifdef _WIN32
    system("pause");
#else
    system("read");
#endif
}

我最近问过如何将模板参数包参数限制为“链”序列?,但我无法使此构造函数工作。

这是传说中的forward_as_tuple用例之一吗?

C++ C++20 variadic-templates perfect-forwarding 类模板

评论

3赞 Igor Tandetnik 11/13/2023
您的类没有元组成员。它有一个成员,该成员是对元组的引用。你正在尝试将该引用绑定到一个临时的。您的意思是要有一个引用类型的成员吗?此引用所指的实际元组应该存储在哪里?
0赞 SKNB 11/13/2023
嗯,这很尴尬;我想我的视野太过狭窄,我看不到显而易见的东西。这不是转发或方法,而是成员是 REFERENCE 的事实。

答: 暂无答案