C++11 Class 模板方法特化和可变参数模板

C++11 Class template method specialization and variadic templates

我正在尝试使用 GCC 和 C++11 构建以下类型的模板化方法:

class Foo
{
private:
    //Device handle
    cudnnHandle_t handle_;
    //Batch sizes
    std::vector<int> batch_;
public:
    Foo(cudnnHandle_t handle, std::vector<int> batch) : handle_(handle), batch_(batch) {}
    template<typename T, typename... Args> T create(Args&&... args)
    {
        if(std::is_base_of<Element,T>::value)
            return T(handle_,args...);
        if(std::is_same<Block,T>::value)
            return T(handle_,batch_,args...);
    }
};

然而,由于 return 语句,编译失败。如果 T 是块,return T(handle_,args...) 将失败,如果 T 是元素基类型 return T(handle,batch_,args...) 将失败.

我尝试了不允许的部分模板特化:

template<typename T, typename... Args> T create(Args&&... args)
{
    return T(handle_,args...);
}
template<typename... Args> Block create<Block>(Args&&... args)
{
    return Block(handle_,batch_,args...);
}

我尝试了完整的模板专业化,显然 GCC 不支持可变参数模板:

template<typename T, typename... Args> T create(Args&&... args)
{
    return T(handle_,args...);
}
template<> Block create<Block,int>(int n)
{
    return Block(handle_,batch_,n);
}

那么我将如何创建像 create 这样的函数?

亲切的问候。

尝试像这样利用 SFINAE

template <typename T, typename... Args,
          typename std::enable_if<std::is_base_of<Element, T>::value>::type* = nullptr>
T create(Args&&... args) {
  return T(handle_, std::forward<Args>(args)...);
}

template <typename T, typename... Args,
          typename std::enable_if<std::is_same<Block, T>::value>::type* = nullptr>
T create(Args&&... args) {
  return T(handle_, batch_, std::forward<Args>(args)...);
}