std::is_same void function(...) 和 void 类型?

std::is_same for void function(...) and void type?

我得到了这段代码:

template <class FunctionType> class Entry {
    std::function<FunctionType> internalFunction;

    template<class... Arguments>
    auto operator()(Arguments... arguments) -> decltype(internalFunction(arguments...)){

        if (std::is_same<decltype(internalFunction(arguments...)), void>::value) {
            internalFunction(arguments...);
        } else {
            auto result = internalFunction(arguments...);

            return result;      
        }
    }
};

条目 class 是 std::function 的包装器。它适用于所有 return 类型,只有一个例外 - void。我无法让它工作。我也试过 std::is_void,return 对于 void(...) 类型的函数不成立。 std::is_same.

也一样

如何解决这个问题?

return internalFunction(arguments...);

即使 internalFunction returns void

也有效

尝试将结果存储在中间对象中是行不通的,因为您无法创建 void 类型的对象,因为它不是对象类型。

你的 if 不起作用,因为 if 是一个 运行 时间条件,编译器仍然需要编译条件的两个分支,因此它们必须都有效C++.

如果您需要创建一个中间结果类型的变量,那么您不能在 void 情况下使用该代码。您可以为函数 returning void:

编写偏特化
template <class FunctionType> class Entry {
    std::function<FunctionType> internalFunction;

    template<class... Arguments>
    auto operator()(Arguments... arguments) -> decltype(internalFunction(arguments...))
    {

        auto result = internalFunction(arguments...);

        return result;      
    }
};

template <class... ArgTypes> class Entry<void(ArgTypes...)> {
    std::function<void(ArgTypes...)> internalFunction;

    template<class... Arguments>
    void operator()(Arguments... arguments) {
        internalFunction(arguments...);
    }
}; 

这不适用于 returning void 的函数,但不适用于 return void 的函子,这样做有点困难。

它遵循另一种解决方案,该解决方案基于 sfinae 而不是 部分专业化
我试图提供一个最小的完整示例。
我还会在示例中介绍 perfect forwarding,但它与问题中的那个有很大不同,所以我决定让它更类似于那个。

#include<functional>
#include<type_traits>


template <class FunctionType> class Entry {
    std::function<FunctionType> internalFunction;

    template<typename R, typename... Args>
    typename std::enable_if<std::is_void<R>::value>::type
    invoke(Args... args) {
        internalFunction(args...);
    }

    template<typename R, typename... Args>
    typename std::enable_if<not std::is_void<R>::value, R>::type
    invoke(Args... args) {
        return internalFunction(args...);
    }

public:
    Entry(std::function<FunctionType> f)
        : internalFunction{f} { }

    template<class... Arguments>
    auto operator()(Arguments... arguments) -> decltype(internalFunction(arguments...)){
        return invoke<typename std::function<FunctionType>::result_type>(arguments...);
    }
};


int f() { return 42; }
void g() { }


int main() {
    Entry<int()> e1(&f);
    e1();
    Entry<void()> e2(&g);
    e2();
}

有关 sfinae 的更多详细信息,请参阅 here