一个永远不能被称为GCC的模板构造函数

A template constructor that never can be called GCC

在下面的代码片段中,GCC 决定调用默认构造函数而不是复制构造函数。构造函数有一个未使用的模板参数,因此无法推导模板参数类型。是的,编译器生成一个默认的复制构造函数并调用它,但似乎编译器的更好行为会发出错误。有人可以解释一下这背后的原因吗?

此外,如果方法中有模板参数,并且该模板参数未在该方法中使用。而且那个模板参数不是方法所在的 class 的,编译器不应该至少给出警告吗?

#include <iostream> 

using namespace std;


template< typename T >
class Test
{};

template< typename T >
class Test1
{
public:

    Test1() : m_t() { std::cout << "Default constructor" << std::endl; }

    template< typename A >
    Test1( const Test1< T >& other ) : m_t( other.m_t ) { std::cout << "Copy constructor" << std::endl; }

    template< typename A >
    Test1( Test1< T >&& other ) : m_t( std::move( other.m_t ) ) { std::cout << "Move constructor" << std::endl; }

    void omg() { std::cout << &m_t << std::endl; }

private:

    T m_t;

};  //  class Test



int main()  
{

    try
    {
        Test1< Test< int > > mm;

        Test1< Test< int > > mm1( mm );

        mm1.omg();

    }
    catch ( const exception& stdException )
    {
        cout << stdException.what() << endl;
    }

    return ( 0 );
}

以上代码运行的结果为:

Default constructor
0x7ffcac82708f

文本 Default constructor 来自行:Test1< Test< int > > mm;。它不是“代替”任何东西。

Test1< Test< int > > mm1( mm ); 调用复制构造函数,它是隐式定义的,因为您没有定义一个或做任何事情来抑制这样的生成。隐式定义的复制构造函数不产生任何输出。这是定义明确的行为,在任何意义上都不是“随机的”。

template< typename A > Test1( const Test1< T >& other ) 不是复制构造函数。 Copy constructors cannot be templates.

gcc 似乎没有关于未使用的模板参数的警告选项。在 this Bugzilla thread 中有人提出要求,开发人员回应说有时不使用模板参数是有意的,例如在只需要其中一些的专业化的情况下。