2014-10-10 56 views
1

我想这取决于类型调用不同的功能于一身的模板功能不同的功能,例如:呼吁取决于类型

template<typename T> 
T func() { 
    static_assert(std::is_same<T, int>::value || /* other allowed types */ , "Type not allowed"); 

    T ret {}; 
    // if T == int 
    funcInt(&ret); 
    // if T == /* other types */ 
    /* other functions */ 

} 

这种事可能吗?

我尝试这样做:

std::function< int(*T)> query; 
if (std::is_same<T, int>::value) { 
    query = funcInt; 
} 

,但是这给了我一个错误:

error: 'T' does not refer to a value

+1

我认为这应该是'std :: function < int(T*)>查询;',假设它是一个指向'T'参数的指针? – Niall 2014-10-10 07:58:27

+0

糟糕!耻辱对我来说,我认为这是一些奇怪的模板错误... – gartenriese 2014-10-10 08:04:02

+0

如果我正确地读了你,你仍然会有错误,因为你的查询不能存储具有不能转换为T * – 2014-10-10 08:06:40

回答

5

is_same可以if语句中使用就好了:

if (std::is_same<T, int>::value>) { /* stuff */ } 
if (std::is_same<T, float>::value) { /* other stuff */ } 

Altough这个检查是理论上在运行时完成,编译器知道编译时的所有值a nd很可能会删除任何死支。缺点是func中的整个代码需要在语法上和语义上形成良好,而不管T是什么。这可能并不总是可行的。

正确的模板上下的方法是这样的:

template<typename> 
struct helper; 

template<> 
struct helper<int> { static void do_work() { /* stuff */ } }; 

template<typename T> 
T func() 
{ 
    static_assert(std::is_same<T, int>::value || /* other allowed types */ , "Type not allowed"); 
    helper<T>::do_work(); 
} 

这允许你写的东西,共同在func并把其余的专业。

OTOH,如果func的签名真的很简单,并且不会有太多的代码重复,那么您也可以专注于func本身。

+0

“[...]”需要形成句法[...]“[...]”。这是否意味着我不能调用一个接受int的函数,因为参数也可以是double,比如? – gartenriese 2014-10-10 08:29:28

+0

我想你可能能够通过SFINAE删除要求以形成良好的要求。 – sjdowling 2014-10-10 08:33:48

+1

@gartenriese你可以,因为一个double可以转换为int,但它可能不是你想要发生的事情。例如,我可能会很奇怪地表达这种想法 - 不会有效的是[例如这样的事情](http://coliru.stacked-crooked.com/a/6f3314362bbd748a)。这对你来说可能不是问题。 – jrok 2014-10-10 08:41:08