试图理解模板

时间:2014-01-21 19:53:19

标签: c++ templates

我写了一个简短的例子,说明我在这里遇到的困惑:

#include <iostream>

template <typename T>
T Add (T t1, T t2)
{
    std::cout << "<typename T>" << std::endl ;
    return t1 + t2 ;
}

template <int>
int Add (int n1, int n2)
{
    std::cout << "<int>" << std::endl ;
    return n1 + n2 ;
}

template <>
int Add (int n1, int n2)
{
    std::cout << "<>" << std::endl ;
    return n1 + n2 ;
}

int main (void) 
{
    Add (5, 4) ;
    Add <int> (5, 4) ;
    Add <> (5, 4) ;

    return 0 ;
}

这个输出是:

<>  
<>  
<>  

所以我想,好吧,最明确的专业化得到优先考虑 但后来我删除了:

template <>
int Add (int n1, int n2)
{
    std::cout << "<>" << std::endl ;
    return n1 + n2 ;
}

输出是:

<typename T>  
<typename T>  
<typename T>  

为什么template <int>版本没有被调用? 什么会导致它被调用?
为什么语法的目的是什么?

2 个答案:

答案 0 :(得分:7)

第二个重载需要一个整数,而不是一个类型。你用

来称呼它
Add< 42 >( 1, 2 );

Live example

澄清:第二个是一个名为Add的独立重载函数,而不是一个特化。你可能会想到这样的事情:

template <>
int Add<int>(int n1, int n2)
{
    std::cout << "<T=int>" << std::endl ;
    return n1 + n2 ;
}

这与您编写的上一个特化完全相同,因此会与之冲突(重新定义它)。 Live example

答案 1 :(得分:4)

您对int s的特化使用了错误的语法。它应该是:

template <>
int Add<int>(int n1, int n2)
{
    std::cout << "<int>" << std::endl ;
    return n1 + n2 ;
}

如果你这样做,你会发现由于多种定义,它与最终专业化发生冲突。