gpt4 book ai didi

C++:静态断言仿函数的参数是常量引用

转载 作者:行者123 更新时间:2023-12-04 08:12:23 27 4
gpt4 key购买 nike

我正在 C++17 中编写模板函数接受仿函数 F作为参数,我想限制传入的仿函数只有一个常量引用参数,其中 T可以是任何类型。
例如:

template <class T> struct my_struct{
std::vector<T> collection;
template <class F> std::vector<T> func(F f){
static_assert(
// CONDITION HERE!,
"f's argument is not const reference"
);

std::vector<T> ret;

std::copy_if(
std::make_move_iterator(this->collection.begin()),
std::make_move_iterator(this->collection.end()),
std::inserter(ret, ret.end()),
f
);

return ret;
}
};
显然,如果 f[](auto v){return true;}func 返回的结果 vector 将有空元素(因为这些元素在添加到结果容器之前被移动)。所以,我需要将可能的输入仿函数限制为 [](const auto& v){} .
我试过这样的事情:
static_assert(
std::is_invocable_v<F, const T&>,
"f's argument is not const reference"
);
但随后 func([](auto v){})不触发断言,因为 T在我的情况下是可复制的。 func([](auto& v){})也通过了测试,因为 auto可以 const T .
但我需要将可能的 lambdas 限制为 func([](const auto& v){}) .

最佳答案

您可能会编写特征(及其局限性),例如:

template <typename Sig> struct callable_traits;

template <typename Ret, typename ...Args>
struct callable_traits<Ret(*)(Args...)>
{
using args = std::tuple<Args...>;
};
// add specialization for C-ellipsis too

template <typename Ret, class C, typename ...Args>
struct callable_traits<Ret(C::*)(Args...) const>
{
using args = std::tuple<Args...>;
};
// add specialization for variant with C-ellipsis, cv-qualifier, ref-qualifier

template <class C>
struct callable_traits<C> : callable_traits<&C::operator()>{};
特征的限制:不处理模板化 operator() (对于通用 lambda),重载 operator() .
进而
template <class T> struct my_struct{
template <class F> void func(F f){
static_assert(
std::is_same_v<std::tuple<const T&>, typename callable_traits<F>::args>,
"f's argument is not const reference"
);

// here goes some code which can possibly call f with rvalue
// reference argument, so I want to avoid situation when the
// argument object is moved or modified. I don't have control
// over this code because it an STL algorithm.
}
};

关于C++:静态断言仿函数的参数是常量引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65888788/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com