微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C++20 概念是否能够将模板函数修复为模板参数问题?

如何解决C++20 概念是否能够将模板函数修复为模板参数问题?

如果你在 C++20 中尝试一些相对简单的东西,它会用 unhelpful error message spam 内爆。

int main() {
    auto as = std::vector{1,3,24,};
    auto bs = std::vector{1,4,10};
    auto cs = std::vector<float>{};
    std::ranges::transform(as,bs,std::back_inserter(cs),std::max);
    std::ranges::copy(cs,std::ostream_iterator<float>(std::cout," "));
}

原因是 std::max 是模板化函数,所以它不起作用。 这可以通过将参数设为 lambda 或创建一个小的辅助函子来轻松解决

但我想知道是否可以使用 C++ 概念来告诉我们想要什么模板实例化? 例如,我们修改了一些 requires 语句,该语句表示如果函子参数是模板,那么该函子的模板参数必须与容器 value_type 匹配。

我怀疑这是可能的,因为我认为在模板重载解析和约束检查开始之前必须知道函子的确切类型,换句话说,没有从概念到调用点的信息“反向传播”。

但我不确定所以我决定问一下。

如果你想知道我尝试了什么,这里是我的代码,但它非常糟糕,我无法编写模板模板参数代码......

但无论如何我希望它说明了这个想法......

template<typename C,typename F>
struct xtransform
{
    xtransform(C& c,F f) : c_(c),f_(f){}
    void operator()(){
    }
    C c_;
    F f_;
};
template<typename C,template<typename> typename F,typename FArg>
requires requires {
    std::is_same_v<typename C::value_type,FArg>;
}
struct xtransform<C,F<FArg>>
{
    xtransform(C& c,F<FArg> f) : c_(c),f_(f){}
    void operator()(C& c,F<FArg> f){
    }
    C c_;
    F<FArg> f_;
};

解决方法

没有

std::max 命名模板函数。具有不完整模板参数列表的模板函数名称在重载解析期间转换为函数。重载解析需要将函数名称转换为指向固定签名的指针,或者使用 () 进行调用。

概念无济于事。

现在你可以使用一个旧的技巧;有一个函数的重载,它在非推导的上下文中使用函数指针。当我编写手动的 std 类函数类型时,正是出于这个原因,我添加了 R(*)(Args...) 重载;当存在类型完全匹配的重载时,允许重载解析。

但这不是基于概念的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。