c++ 使用任意数量的参数调用任何noexcept的概念

mgdq6dx1  于 2023-11-19  发布在  其他
关注(0)|答案(1)|浏览(78)

我尝试使用Concept来约束模板参数,使其只允许noexcept类型的可调用对象。
例如:

template<NoExceptFunc Fn>
void foo(Fn invocable) noexcept {
  invocable();
}

字符串
我遇到的困难是,invocable应该是任何类型的invocable(自由函数,lambda,...),并允许任何数量的参数。
编辑:感谢How can unspecified types be used in C++20 'requires' expressions?,我知道这在一般情况下是不可能做到的,你需要知道invocable实际上是什么,然后才能约束它。
尽管如此,即使我知道invocable实际上是什么,我也不知道如何表达contrain,见下文。
以下

template <typename T, typename... Args>
concept NoExceptFunc = requires(T &&f, Args &&...args) { requires noexcept(f(args...)); };


工作,但需要显式给出参数类型,例如:

template<NoExceptFunc<int, int> Fn>
void foo(Fn invocable) noexcept {
  invocable(0, 1);
}


问题是,我不知道如何在以下情况下指定参数:

template <NoExceptFunc<??> Fn>
void foo(Fn f) noexcept {
    f(1);
    f("hello", "world");
}

int main() {
    auto lambda = [](auto&& a, auto&&... rest) {
        std::cout << a;
        if constexpr(sizeof...(rest) != 0) {
            std::cout << (rest << ...);
        }
        std::cout << std::endl; 
    };

    foo(lambda);
}


我怎么能说参数可以是OR <const char*,const char*>呢?

wmomyfyw

wmomyfyw1#

如果你可以使用模板化的结构来推导参数,这适用于非泛型/非可变参数的可调用对象:

#include <iostream>
#include <type_traits>

template <typename T, typename = void>
struct is_noexcept : std::false_type
{};
template <typename T>
struct is_noexcept<T, std::void_t<decltype(&T::operator())>>
: std::conditional_t<is_noexcept<decltype(&T::operator())>::value, std::true_type, std::false_type>
{};
template <typename Ret, typename ...Args>
struct is_noexcept<Ret(*)(Args...) noexcept> : std::true_type
{};
template <typename Ret, typename C, typename ...Args>
struct is_noexcept<Ret(C::*)(Args...) noexcept> : std::true_type
{};
template <typename Ret, typename C, typename ...Args>
struct is_noexcept<Ret(C::*)(Args...) const noexcept> : std::true_type
{};

// turn into a concept
template <typename Fn>
concept NoExceptFunc = is_noexcept<Fn>::value;

字符串
使用方法:

void func_noexcept(int) noexcept
{
  std::cout << "Function\n";
}

template<NoExceptFunc Fn>
void foo(Fn invocable) noexcept {
  invocable(1);
}

int main()
{
  foo(func_noexcept);
    
  foo([](int x) noexcept { std::cout << "Lambda\n"; });
}

相关问题