2

如何从模板仿函数包装器返回任意类型(void 或 non-void)?我将包装器用于前置条件和后置条件,因此我需要将返回的值存储在局部变量中,然后再从包装器返回它。但是当返回的类型是 void 时,编译器会给出错误,因为变量不能有 void 类型。在这里可以做什么?

template <typename Functor, typename... Args>
auto Decorate(Functor f, Args&&... args)
-> decltype(f(std::forward<Args>(args)...)) {
    // preconditions
    const auto result = f(std::forward<Args>(args)...);
    // postconditions
    return result;
}
4

2 回答 2

5

在合适的类的构造函数/析构函数中运行你的前置条件和后置条件并直接返回值!只要您不需要触摸后置条件中的返回值,这应该不是问题!

struct condition
{
    condition() { /* do pre-condition checks */ }
    ~condition() { /* do post-condition checks */ }
    condition(condition&) = delete;
    void operator= (condition&) = delete;
};
template <typename Functor, typename... Args>
auto Decorate(Functor f, Args&&... args)
    -> decltype(f(std::forward<Args>(args)...)) {
    condition checker;
    return f(std::forward<Args>(args)...);
}
于 2013-08-29T17:35:40.150 回答
1

使用 sfinae:

#include <type_traits>

template <typename Functor, typename... Args>
auto Decorate(Functor f, Args&&... args)
    -> typename std::enable_if<std::is_same<decltype(f(std::forward<Args>(args)...)), void>::value, void>::type
{
    // preconditions
    f(std::forward<Args>(args)...);
    // postconditions
    return;
}

template <typename Functor, typename... Args>
auto Decorate(Functor f, Args&&... args)
    -> typename std::enable_if<!std::is_same<decltype(f(std::forward<Args>(args)...)), void>::value, decltype(f(std::forward<Args>(args)...))>::type
{
    // preconditions
    auto result = f(std::forward<Args>(args)...);
    // postconditions
    return result;
}

测试:

void f(int x) {
    std::cout << "f(" << x << ")" << std::endl;
    return;
}

int g(int x) {
    std::cout << "g(" << x << ")" << std::endl;
    return x * x;
}

int main()
{       
    Decorate(f, 3);
    std::cout << Decorate(g, 3);
    return 0;
}

f(3)
g(3)
9

于 2013-08-29T17:36:45.070 回答