2016-08-18 80 views
4

我有一些可变参数模板方法,它看起来像这样:C++可变参数模板方法专业化

template<typename ... Args> 
    void Invoke(const char* funcName, Args ... args) const; 

    template<typename ... Args> 
    void Invoke(const char* funcName, Args ... args) const 
    { 
     SPrimitive params[] = { args ... }; 
     SomeOtherInvoke(funcName, params, sizeof ... (Args)); 
    } 

这里SPrimitive - 只是一个简单的结构与任何原始类型的构造函数。

我想为一些复杂类型再做一个Invoke定义。这里是我的问题: 是否有可能在C++ 11/14中创建可变参数模板方法专业化? 我的意思是这样(为简单起见让我喜欢的类型将是int):

template<int ... Args> 
    void Invoke(const char* funcName, Args ... args) 
    { 
     int params[] = { args ... }; 
     SomeComplexInvoke(funcName, params, sizeof ... (Args)); 
    } 

在这里,我希望有一个专业化,这需要int类型的任何参数算的,所以我可以调用它,就像这样:

Invoke("method", 2, 4 ,9); 
+2

不是专业化,但你可以与超载和SFINAE。 – Jarod42

+0

但'std :: initializer_list '似乎更合适(使用'Invoke(“method”{2,4,9})'语法)。 – Jarod42

回答

4

作为@ Jarod42提到,它不应该与专业化。在您的例子中,你想要的东西,特别的,如果所有的参数类型是int,让我们写一个模板,将检查:

template<typename ref, typename t, typename ...types> 
struct all_same { 
     static constexpr bool value = std::is_same<ref, t>::value && all_same<ref, types...>::value; 
}; 

template<typename ref, typename t> 
struct all_same<ref, t> { 
     static constexpr bool value = std::is_same<ref, t>::value; 
}; 

它检查第一类参数是否等于所有其他类型的参数。

template<typename ... Args> 
void Invoke(const char* funcName, Args ... args) 
{ 
    using params_type = typename std::conditional<all_same<int, Args...>::value, int, SPrimitive>::type; 
    params_type params[] = { args ... }; 
    SomeOtherInvoke(funcName, params, sizeof ... (Args)); 
} 

现在演示的缘故,让我们定义:然后在Invoke,我们应该根据args...类型选择params

struct SPrimitive{ 
}; 

void SomeOtherInvoke(const char*, SPrimitive*, size_t) { 
     std::cout << "Invoked for SPrimitive\n"; 
} 

void SomeOtherInvoke(const char*, int*, size_t) { 
     std::cout << "Invoked for int\n"; 
} 

,并呼吁

Invoke("foo", SPrimitive()); 
Invoke("foo", SPrimitive(), SPrimitive()); 
Invoke("foo", 1, 2, 3, 4); 

输出是:

Invoked for SPrimitive 
Invoked for SPrimitive 
Invoked for int 

这就是你要求的。

+0

谢谢,它正是我正在寻找的! – Michael