C ++静态模板类成员作为朋友模板函数的默认参数

时间:2019-02-25 03:54:19

标签: c++ templates default-parameters default-arguments function-templates

为什么使用静态模板类成员作为好友模板函数默认参数会给我C ++中的编译错误?怎么打?

代码如下:

#include <iostream>

template<typename T>
void func(T n);

template<typename T>
class MyClass
{
private:
    static T statTemp;
public:
    friend void func<>(T n);
};

template<typename T>
T MyClass<T>::statTemp(1);

template<typename T>
void func(T n = MyClass<T>::statTemp)
{
    std::cout << n << std::endl;
}

int main()
{
    func<int>();
}

编译时:

g ++ -std = c ++ 11 main.cpp

error: redeclaration of 'template<class T> void func(T)' may not have default arguments [-fpermissive]
 void func(T n = MyClass<T>::statTemp)
      ^~~~
In function 'int main()':
error: no matching function for call to 'func<int>()'
  func<int>();
            ^
note: candidate: 'template<class T> void func(T)'
 void func(T n = MyClass<T>::statTemp)
      ^~~~
note:   template argument deduction/substitution failed:
note:   candidate expects 1 argument, 0 provided
  func<int>();
            ^

Visual Studio 2017

C2672   "func": No matching overloaded function found.

2 个答案:

答案 0 :(得分:2)

该语言不允许在相同作用域的函数的后续声明中添加模板函数的默认参数。

C ++ 17标准草案n4659指出:

  

11.3.6默认参数[dcl.fct.default]
  ...
  4对于非模板函数,可以在同一作用域的函数的后续声明中添加默认参数。

由于func是模板函数,因此不允许在同一范围内的func的后续声明中添加默认参数。

因此,GCC正确拒绝了此请求:

error: redeclaration of 'template<class T> void func(T)' may not have default arguments [-fpermissive]
 void func(T n = MyClass<T>::statTemp)

答案 1 :(得分:0)

我让您的程序可以编译,但是,老实说,我不确定我到底做了什么。我只能直视我的直觉,并尽我所能解释我的所作所为:

#include <iostream>

template<typename T>
void func();

template<typename T>
class MyClass
{
private:
    static T statTemp;
public:
    friend void func<T>();
};

template<typename T>
T MyClass<T>::statTemp(1);

template<typename T>
void func()
{
    T n = MyClass<T>::statTemp;
    std::cout << n << std::endl;
}

int main()
{
    func<int>();
}

首先,我注意到您原来的funct(T n)是在文件顶部声明的,它希望将T n传递到函数中。总的来说,您不会这样做。因此,当您调用func(T n)并没有将任何内容传递给该函数时,编译器会生气,因为它希望传递一些东西。也许您可以做的是重载该函数,在其中调用另一个func(T n)通过T n = MyClass<T>::statTemp;

最后,您的friend void func<>()没有模板类型,因此编译器也对此感到恼火。

我希望有帮助。