模板函数默认参数

Template function default parameter

//template.h using MSVC++ 2010
#pragma  once
#include <iostream>
using std::ostream;
template <typename T, typename U> class Pair {
  private:
    T first;
    U second;

  public:

    // Pair() ;
    Pair ( T x = T() , U y = U() ) ;
    template<typename T, typename U> 
    friend ostream& operator<< ( ostream& thisPair, Pair<T, U>& otherPair );

};
template <typename T, typename U> 
Pair<T, U>::Pair ( T x , U y ) : first ( T ( x ) ), second ( U ( y ) ) 
{cout << x << y;}

template <typename T, typename U> 
ostream& operator<< ( ostream& os, Pair<T, U>& otherPair )
{
    os << "First: " << otherPair.first 
<< " "<< "Second: " << otherPair.second << endl;
    return os;
}

//template.cpp
int main()
{
    int a = 5, b = 6;
    Pair<int,int> pair4();
    Pair<int, int> pair1 ( a, b );
    cout<<pair4;
    cout<<pair1;
    return 0;
}

如何让构造函数或成员函数取默认值? 上面的代码在使用 cout 语句时给出了 pair4 的链接器错误。 该代码在 cout< 中使用单个默认构造函数来模拟采用 0,1 或 2 个参数的构造函数

除了阴影模板参数(MSVC++ 错误地忽略)等其他错误外,问题在于:

Pair<int,int> pair4();

这声明了一个函数而不是一个变量。这是因为它在语法上可以是两者,并且 C++ 标准选择了最令人烦恼的解析:任何可以被编译器解释为声明的东西,都将被解释为声明。 linker 错误是您尝试打印到从未定义(没有地址)的函数的 cout 地址。

旁注:在 GCC 和 Clang 中,您实际上可以 link 这是因为地址会立即转换为 bool for operator <<(没有用于打印函数指针的运算符ostreambool 是唯一可用的隐式转换),这将始终导致 true(声明的函数的地址永远不会是 nullptr),因此地址本身被优化掉.

修复非常简单:

Pair<int,int> pair4;