c++ 将左值和右值绑定到可变参数类模板参数

t40tm48m  于 2023-07-01  发布在  其他
关注(0)|答案(2)|浏览(151)

我有一个类模板,它接受可变数量的模板参数。类有一些函数接受与类的模板参数相对应的参数。我希望这些函数绑定到左值和右值。我如何才能做到这一点?

template<class ...C>
class Graph {
public:
    Graph(C &...Context); // <- Only lvalues
    Graph(C &&...Context); // <- Only rvalues
    Graph(auto &&...Context); // <- Both lvalues and rvalues, but does not enforce that the types correspond to ...C
};

似乎不可能在类内部创建concept。我可以在类之外创建一个概念,然后传递类模板包和函数模板包,并以某种方式验证它们吗?或者我可以在函数中添加一个requires子句来解决这个问题吗?
我已经发现了一些类似的问题,但它们相当古老,所以没有使用concept s的答案。

hjzp0vay

hjzp0vay1#

std::constructible_from概念可能会有所帮助:

template <class... C>
class Graph {
public:
    template <typename... Ts>
    requires((std::constructible_from<C, Ts> && ...))
    Graph(Ts&&...);
};

Demo
或更严格的std::convertible_to

template <class... C>
class Graph {
public:
    template <typename... Ts>
    requires((std::convertible_to<Ts, C> && ...))
    Graph(Ts&&...);
};

Demo
std::same_as

template <class... C>
class Graph {
public:
    template <typename... Ts>
    requires(((std::same_as<Ts&&, C&&>
               || (std::same_as<Ts&&, C&> /*&& !std::is_rvalue_reference_v<C>*/))
            && ...))
    Graph(Ts&&...);
};

Demo

gfttwv5a

gfttwv5a2#

听起来你想要的是

template<class... C>
class Graph {
public:
    template<class... Ts>
    requires (std::same_as<Ts&, C&> and ...)
    Graph(Ts&&... Context);
};

为了简洁,这利用了引用折叠规则。
如果你愿意,你可以为此写一个概念(在这里完整地写出来):

template<class T, class U>
concept same_as_or_lvalue_reference_to = std::same_as<T, U> or std::same_as<T, U&>;

template<class... C>
class Graph {
public:
    Graph(same_as_or_lvalue_reference_to<C> auto&&... Context);
};

相关问题