Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C+中的Python风格装饰器+;17 我正在用最新的C++技术制作一个Python风格的装饰器。我已经在这里看到了一些解决方案(),但我想知道是否可以做得更好。在别人的帮助下()我想出了以下解决方案 template<typename TWrapped> auto DurationAssertDecorator(const std::chrono::high_resolution_clock::duration& maxDuration, TWrapped&& wrapped) { return [wrapped = std::forward<TWrapped>(wrapped), maxDuration](auto&&... args) { const auto startTimePoint = std::chrono::high_resolution_clock::now(); static_assert(std::is_invocable<TWrapped, decltype(args)...>::value, "Wrapped object must be invocable"); if constexpr (!(std::is_void<decltype(wrapped(std::forward<decltype(args)>(args)...))>::value)) { // return by reference will be here not converted to return by value? //auto result = wrapped(std::forward<decltype(args)>(args)...); decltype(wrapped(std::forward<decltype(args)>(args)...)) result = wrapped(std::forward<decltype(args)>(args)...); const auto endTimePoint = std::chrono::high_resolution_clock::now(); const auto callDuration = endTimePoint - startTimePoint; assert(callDuration <= maxDuration); return result; } else { wrapped(std::forward<decltype(args)>(args)...); const auto endTimePoint = std::chrono::high_resolution_clock::now(); const auto callDuration = endTimePoint - startTimePoint; assert(callDuration <= maxDuration); } }; } 模板 自动DurationAssertDecorator(常数标准::时钟::高分辨率时钟::duration&maxDuration,TWrapped&wrapped) { 返回[wrapped=std::forward(wrapped),maxDuration](自动参数) { const auto startTimePoint=std::chrono::高分辨率时钟::now(); 静态_断言(std::is_invocable::value,“包装的对象必须是invocable”); 如果constexpr(!(std::is_void::value)) { //按引用返回是否在此处转换为按值返回? //自动结果=包装(标准::转发(参数)…); decltype(wrapped(std::forward(args)…)结果=wrapped(std::forward(args)…); const auto endTimePoint=std::chrono::high_resolution_clock::now(); const auto callDuration=endTimePoint-startTimePoint; assert(callDuration_C++_Lambda_Stl_C++17 - Fatal编程技术网

C+中的Python风格装饰器+;17 我正在用最新的C++技术制作一个Python风格的装饰器。我已经在这里看到了一些解决方案(),但我想知道是否可以做得更好。在别人的帮助下()我想出了以下解决方案 template<typename TWrapped> auto DurationAssertDecorator(const std::chrono::high_resolution_clock::duration& maxDuration, TWrapped&& wrapped) { return [wrapped = std::forward<TWrapped>(wrapped), maxDuration](auto&&... args) { const auto startTimePoint = std::chrono::high_resolution_clock::now(); static_assert(std::is_invocable<TWrapped, decltype(args)...>::value, "Wrapped object must be invocable"); if constexpr (!(std::is_void<decltype(wrapped(std::forward<decltype(args)>(args)...))>::value)) { // return by reference will be here not converted to return by value? //auto result = wrapped(std::forward<decltype(args)>(args)...); decltype(wrapped(std::forward<decltype(args)>(args)...)) result = wrapped(std::forward<decltype(args)>(args)...); const auto endTimePoint = std::chrono::high_resolution_clock::now(); const auto callDuration = endTimePoint - startTimePoint; assert(callDuration <= maxDuration); return result; } else { wrapped(std::forward<decltype(args)>(args)...); const auto endTimePoint = std::chrono::high_resolution_clock::now(); const auto callDuration = endTimePoint - startTimePoint; assert(callDuration <= maxDuration); } }; } 模板 自动DurationAssertDecorator(常数标准::时钟::高分辨率时钟::duration&maxDuration,TWrapped&wrapped) { 返回[wrapped=std::forward(wrapped),maxDuration](自动参数) { const auto startTimePoint=std::chrono::高分辨率时钟::now(); 静态_断言(std::is_invocable::value,“包装的对象必须是invocable”); 如果constexpr(!(std::is_void::value)) { //按引用返回是否在此处转换为按值返回? //自动结果=包装(标准::转发(参数)…); decltype(wrapped(std::forward(args)…)结果=wrapped(std::forward(args)…); const auto endTimePoint=std::chrono::high_resolution_clock::now(); const auto callDuration=endTimePoint-startTimePoint; assert(callDuration

C+中的Python风格装饰器+;17 我正在用最新的C++技术制作一个Python风格的装饰器。我已经在这里看到了一些解决方案(),但我想知道是否可以做得更好。在别人的帮助下()我想出了以下解决方案 template<typename TWrapped> auto DurationAssertDecorator(const std::chrono::high_resolution_clock::duration& maxDuration, TWrapped&& wrapped) { return [wrapped = std::forward<TWrapped>(wrapped), maxDuration](auto&&... args) { const auto startTimePoint = std::chrono::high_resolution_clock::now(); static_assert(std::is_invocable<TWrapped, decltype(args)...>::value, "Wrapped object must be invocable"); if constexpr (!(std::is_void<decltype(wrapped(std::forward<decltype(args)>(args)...))>::value)) { // return by reference will be here not converted to return by value? //auto result = wrapped(std::forward<decltype(args)>(args)...); decltype(wrapped(std::forward<decltype(args)>(args)...)) result = wrapped(std::forward<decltype(args)>(args)...); const auto endTimePoint = std::chrono::high_resolution_clock::now(); const auto callDuration = endTimePoint - startTimePoint; assert(callDuration <= maxDuration); return result; } else { wrapped(std::forward<decltype(args)>(args)...); const auto endTimePoint = std::chrono::high_resolution_clock::now(); const auto callDuration = endTimePoint - startTimePoint; assert(callDuration <= maxDuration); } }; } 模板 自动DurationAssertDecorator(常数标准::时钟::高分辨率时钟::duration&maxDuration,TWrapped&wrapped) { 返回[wrapped=std::forward(wrapped),maxDuration](自动参数) { const auto startTimePoint=std::chrono::高分辨率时钟::now(); 静态_断言(std::is_invocable::value,“包装的对象必须是invocable”); 如果constexpr(!(std::is_void::value)) { //按引用返回是否在此处转换为按值返回? //自动结果=包装(标准::转发(参数)…); decltype(wrapped(std::forward(args)…)结果=wrapped(std::forward(args)…); const auto endTimePoint=std::chrono::high_resolution_clock::now(); const auto callDuration=endTimePoint-startTimePoint; assert(callDuration,c++,lambda,stl,c++17,C++,Lambda,Stl,C++17,我已经意识到,如果我在调用前和调用后活动中使用RAII对象,我可以大大简化代码。不再需要处理void和non-void返回值 template<typename TWrapped> auto DurationAssertDecorator(const std::chrono::high_resolution_clock::duration& maxDuration, TWrapped&& wrapped) { return [wrapped = std

我已经意识到,如果我在调用前和调用后活动中使用RAII对象,我可以大大简化代码。不再需要处理void和non-void返回值

template<typename TWrapped>
auto DurationAssertDecorator(const std::chrono::high_resolution_clock::duration& maxDuration, TWrapped&& wrapped)
{
    return [wrapped = std::forward<TWrapped>(wrapped), maxDuration](auto&&... args) mutable
    {
        static_assert(std::is_invocable<TWrapped, decltype(args)...>::value, "Wrapped object must be invocable");

        struct Aspect
        {
            // Precall logic goes into the constructor
            Aspect(const std::chrono::high_resolution_clock::duration& maxDuration)
                : _startTimePoint(std::chrono::high_resolution_clock::now())
                , _maxDuration(maxDuration)
            {}

            // Postcall logic goes into the destructor
            ~Aspect()
            {
                const auto endTimePoint = std::chrono::high_resolution_clock::now();
                const auto callDuration = endTimePoint - _startTimePoint;
                assert(callDuration <= _maxDuration);
            }

            const std::chrono::high_resolution_clock::time_point _startTimePoint;
            const std::chrono::high_resolution_clock::duration& _maxDuration;
        } aspect(maxDuration);

        return wrapped(std::forward<decltype(args)>(args)...);
    };
}
我还想使用非常量函子,比如可变lambdas:

auto wrappedFunctor = DurationAssertDecorator(1s, 
    [firstCall = true](const double temperature) mutable
    {
        if (firstCall)
        {
            firstCall = false;
            return temperature;
        }
        std::this_thread::sleep_for(2s);
        return temperature;
    });

所以我对这个解决方案很满意。

你确定要从lambda capture中的
包装
移动吗?似乎
std::forward
可能是一个更好的方法。谢谢,我认为你是对的:forward将与正常和移动引用一起工作。我已经在问题中修改了代码
template<typename TWrapped>
auto DurationAssertDecorator(const std::chrono::high_resolution_clock::duration& maxDuration, TWrapped&& wrapped)
{
    return [wrapped = std::forward<TWrapped>(wrapped), maxDuration](auto&&... args)
    {
        const auto startTimePoint = std::chrono::high_resolution_clock::now();

        static_assert(std::is_invocable<TWrapped, decltype(args)...>::value, "Wrapped object must be invocable");

        if constexpr (!(std::is_void<decltype(wrapped(std::forward<decltype(args)>(args)...))>::value))
        {
            // return by reference will be here not converted to return by value?
            //auto result = wrapped(std::forward<decltype(args)>(args)...);

            decltype(wrapped(std::forward<decltype(args)>(args)...)) result = wrapped(std::forward<decltype(args)>(args)...);

            const auto endTimePoint = std::chrono::high_resolution_clock::now();
            const auto callDuration = endTimePoint - startTimePoint;
            assert(callDuration <= maxDuration);

            return result;
        }
        else
        {
            wrapped(std::forward<decltype(args)>(args)...);

            const auto endTimePoint = std::chrono::high_resolution_clock::now();
            const auto callDuration = endTimePoint - startTimePoint;
            assert(callDuration <= maxDuration);
        }
    };
}
template<typename TWrapped>
auto DurationAssertDecorator(const std::chrono::high_resolution_clock::duration& maxDuration, TWrapped&& wrapped)
{
    return [wrapped = std::forward<TWrapped>(wrapped), maxDuration](auto&&... args) mutable
    {
        static_assert(std::is_invocable<TWrapped, decltype(args)...>::value, "Wrapped object must be invocable");

        struct Aspect
        {
            // Precall logic goes into the constructor
            Aspect(const std::chrono::high_resolution_clock::duration& maxDuration)
                : _startTimePoint(std::chrono::high_resolution_clock::now())
                , _maxDuration(maxDuration)
            {}

            // Postcall logic goes into the destructor
            ~Aspect()
            {
                const auto endTimePoint = std::chrono::high_resolution_clock::now();
                const auto callDuration = endTimePoint - _startTimePoint;
                assert(callDuration <= _maxDuration);
            }

            const std::chrono::high_resolution_clock::time_point _startTimePoint;
            const std::chrono::high_resolution_clock::duration& _maxDuration;
        } aspect(maxDuration);

        return wrapped(std::forward<decltype(args)>(args)...);
    };
}
auto wrappedFunctor = DurationAssertDecorator(1s, [](const double temperature)  { return temperature; });
auto wrappedFunctor = DurationAssertDecorator(1s, 
    [firstCall = true](const double temperature) mutable
    {
        if (firstCall)
        {
            firstCall = false;
            return temperature;
        }
        std::this_thread::sleep_for(2s);
        return temperature;
    });