从概念中推导模板参数值

发布于 2025-02-09 21:17:54 字数 820 浏览 0 评论 0原文

我继续我的c ++ 20概念(ual)jourrney ...我想通过从谓词参数中推论模板参数t来简化以下代码,以便客户端代码不必精确t的类型,如果可以从P1推导。

我想这是可能的,我只是不知道语法:我尝试了各种形式的模板模板 +需要子句,但没有成功的汇编。

有领先吗?

#include<concepts>
#include<utility>
#include<string>

template<class T, std::predicate<T> P1>
struct Foo
{
    P1 _f;
    Foo(P1 &&f): _f(std::forward<P1>(f)) {}
};

template<class T, std::predicate<T> P1>
auto make_foo(P1 &&f)
{
return Foo<T, P1>(std::forward<P1>(f));
}

int main()
{
    auto fun = [](const std::string &s){return s == "toto";};
    // auto my_foo = make_foo(fun); // candidate template ignored: couldn't infer template argument 'T'
    auto my_foo = make_foo<std::string>(fun);
    return 0;
}

I continue my C++20 concept(ual) jourrney... I would like to simplify the following code by deducing the template parameter T from the predicate argument, so that the client code does not have to precise the type of T if it can be deduced from P1.

I guess it is possible, I just don't know the syntax: I tried various forms of template template + requires clause, but without having a successful compilation.

Any lead?

#include<concepts>
#include<utility>
#include<string>

template<class T, std::predicate<T> P1>
struct Foo
{
    P1 _f;
    Foo(P1 &&f): _f(std::forward<P1>(f)) {}
};

template<class T, std::predicate<T> P1>
auto make_foo(P1 &&f)
{
return Foo<T, P1>(std::forward<P1>(f));
}

int main()
{
    auto fun = [](const std::string &s){return s == "toto";};
    // auto my_foo = make_foo(fun); // candidate template ignored: couldn't infer template argument 'T'
    auto my_foo = make_foo<std::string>(fun);
    return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

欢烬 2025-02-16 21:17:54

std :: function具有良好的 dectuct /a>要获得可呼叫的类型:

// Replacement for `std::function<T(U)>::argument_type`
template<typename T> struct single_function_argument;
template<typename Ret, typename Arg> struct single_function_argument<std::function<Ret(Arg)>> { using type = Arg; };

// Deduction guide
template<class P1>
Foo(P1 &&) -> Foo<typename single_function_argument<decltype(std::function{std::declval<P1>()})>::type, P1>;

template<class P1>
auto make_foo(P1 &&f)
{
    // Use CTAD
    return Foo(std::forward<P1>(f));
}

// Can still specify type manually if you want
template<class T, std::predicate<T> P1>
auto make_foo(P1 &&f)
{
    return Foo<T, P1>(std::forward<P1>(f));
}

int main() {
    auto fun = [](const std::string &s){return s == "toto";};
    auto my_foo1 = Foo(fun);
    auto my_foo2 = make_foo(fun);
}

您必须走这种循环的原因是fun的类型满足所有std :: predicate&lt; const std ::字符串&amp;&gt;std :: predicate&lt; const&car*&gt;std :: predicate&lt; typeimplecity&lt; typeimplecorlicyConveribletlybletostostring&gt;,没有独特的方式获得类型的独特方法对于t。通用lambdas [](const auto&amp; s){return s ==“ toto”也失败了。 },因此您需要使用make_foo&lt; std :: string&gt;(fun)

std::function has good deduction guides to get the type of a callable:

// Replacement for `std::function<T(U)>::argument_type`
template<typename T> struct single_function_argument;
template<typename Ret, typename Arg> struct single_function_argument<std::function<Ret(Arg)>> { using type = Arg; };

// Deduction guide
template<class P1>
Foo(P1 &&) -> Foo<typename single_function_argument<decltype(std::function{std::declval<P1>()})>::type, P1>;

template<class P1>
auto make_foo(P1 &&f)
{
    // Use CTAD
    return Foo(std::forward<P1>(f));
}

// Can still specify type manually if you want
template<class T, std::predicate<T> P1>
auto make_foo(P1 &&f)
{
    return Foo<T, P1>(std::forward<P1>(f));
}

int main() {
    auto fun = [](const std::string &s){return s == "toto";};
    auto my_foo1 = Foo(fun);
    auto my_foo2 = make_foo(fun);
}

The reason you have to go this round-about way is that the type of fun satisfies all of std::predicate<const std::string&>, std::predicate<const char*>, std::predicate<TypeImplicitlyConveribleToString>, there's no unique way to get a type for T. This approach also fails with generic lambdas [](const auto& s) { return s == "toto"; }, so you would need to use make_foo<std::string>(fun).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文