C++ 模板特化 : change return type of operator()?

标签 c++ templates c++14 template-specialization return-type

在下面的类中我定义了一个 operator()返回 return_T 的 vector :

#include <vector>

template <typename return_T, typename ... arg_T>
class A
{
public:
    std::vector<return_T> operator()(arg_T... args);
};

这有效,除了 return_T = void 的情况, 因为 vector<void>是不可能的。所以我需要定义 A<void, arg_T>::operator() 的特化不知何故。我正在试验以下代码:

#include <vector>

template <typename return_T, typename ... arg_T>
class A
{
public:
    auto operator()(arg_T... args);
};

template<typename return_T, typename... arg_T>
auto A<return_T, arg_T...>::operator()(arg_T... args) -> typename std::enable_if<!std::is_void<return_T>::value, std::vector<return_T>>::type
{ }

template<typename return_T, typename... arg_T>
auto A<void, arg_T...>::operator()(arg_T... args) -> void
{ }

但是编译器不喜欢它。

error : prototype for 'typename std::enable_if<(! std::is_void<_Tp>::value), std::vector<_Tp> >::type A<return_T, arg_T>::operator()(arg_T ...)' does not match any in class 'A<return_T, arg_T>'
   auto A<return_T, arg_T...>::operator()(arg_T... args) -> typename std::enable_if<!std::is_void<return_T>::value, std::vector<return_T>>::type

error : candidate is: auto A<return_T, arg_T>::operator()(arg_T ...)
       auto operator()(arg_T... args);
            ^

error : invalid use of incomplete type 'class A<void, arg_T ...>'
   auto A<void, arg_T...>::operator()(arg_T... args) -> void
                                                        ^

当然,我可以用 void operator() 轻松编写第二个类,但我很好奇是否也可以用一个类(class)来完成。那么我的问题是:这可能吗?

最佳答案

#include <type_traits>
#include <utility>
#include <vector>

template <typename return_T, typename... arg_T>
class A
{
public:
    auto operator()(arg_T... args)
    {
        return invoke(std::is_void<return_T>{}, std::forward<arg_T>(args)...);
    }

private:
    void invoke(std::true_type, arg_T&&... args)
    {
    }

    std::vector<return_T> invoke(std::false_type, arg_T&&... args)
    {
        return {};
    }
};

测试:

int main()
{
    A<int, char, short> a;    
    static_assert(std::is_same<decltype(a('x', 5)), std::vector<int>>{}, "!");

    A<void, char, short> b;
    static_assert(std::is_same<decltype(b('x', 5)), void>{}, "!");    
}

DEMO

关于C++ 模板特化 : change return type of operator()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33469666/

相关文章:

c++ - 使用boost spirit X3解析变体列表

c++ - 通用 lambda、继承和尾随返回类型 : is this valid code?

c++ - C++ 中的调用时间改变了我的 struct tm

c++ - 带有自定义分配器的 std::string

c++ - 此错误消息是什么意思以及如何修复它

html - 出现错误 : UIInstructions cannot be cast to org. primefaces.model.menu.MenuElement

c++ - 使用 enable_if 匹配数字作为函数参数

c++ - 对于具有附加(非推导)模板参数的函数,ADL 失败(或未完成?)

c++ - 在模板函数 C++ 中的 F&&,Args &&... 参数之后添加另一个函数作为参数

c++ - 为什么在此代码中出现运行时错误SIGSEGV