C++ 类模板中的模板构造函数 - 如何为第二个参数显式指定模板参数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13002368/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:52:34  来源:igfitidea点击:

Template constructor in a class template - how to explicitly specify template argument for the 2nd parameter?

c++templates

提问by Gob00st

Template constructor in a class template - how to explicitly specify template argument for the 2nd parameter?

类模板中的模板构造函数 - 如何为第二个参数显式指定模板参数?

compile error when tried to explicit specify template argument for constructor 2. How should I do it if I really want to explicit call constructor 2 ?

尝试为构造函数 2 显式指定模板参数时出现编译错误。如果我真的想显式调用构造函数 2 应该怎么做?

Please note this is the same situation for boost::shared_ptr when you want to explicitly specify the deleter type.

请注意,当您要明确指定删除器类型时,这与 boost::shared_ptr 的情况相同。

N.B. For non-construction function foo(), explicitly specify works fine.

注意对于构造函数 foo(),明确指定工作正常。

N.B I know it works fine withoutspecify the 2nd one explicitly for the constructor 2 as template argument deduction normally just works fine, I am just curious how to specify it explicitly.

NB我知道它没有为构造函数2明确指定第二个就可以正常工作,因为模板参数推导通常可以正常工作,我只是好奇如何明确指定它。

template<class T> class TestTemplate {
public:
    //constructor 1
    template<class Y> TestTemplate(T * p) {
        cout << "c1" << endl;
    }

    //constructor 2
    template<class Y, class D> TestTemplate(Y * p, D d) {
        cout << "c2" << endl;
    }

    template<class T, class B>
    void foo(T a, B b) {
        cout << "foo" << endl;
    }
};

int main() {
    TestTemplate<int> tp(new int());//this one works ok call constructor 1
    //explicit template argument works ok
    tp.foo<int*, string>(new int(), "hello");

    TestTemplate<int> tp2(new int(),2);//this one works ok call constructor 2

    //compile error when tried to explicit specify template argument for constructor 2
    //How should I do it if I really want to explicit call constructor 2?
    //TestTemplate<int*, int> tp3(new int(), 2); //wrong
    //TestTemplate<int*> tp3<int*,int>(new int(), 2); //wrong again

    return 0;
}

回答by Jesse Good

Fixing your code, the following would work:

修复您的代码,以下内容将起作用:

template<class T> class TestTemplate {
public:
    //constructor 1
    template<class Y> TestTemplate(Y * p) {
        cout << "c1" << endl;
    }

    //constructor 2
    template<class Y, class D> TestTemplate(Y * p, D d) {
        cout << "c2" << endl;
    }

    template<class A, class B>
    void foo(A a, B b) {
        cout << "foo" << endl;
    }
};

int main() {
    TestTemplate<int> tp(new int());

    tp.foo<int*, string>(new int(), "hello");

    TestTemplate<int> tp2(new int(),2);
}

You cannot use Tfor the class template parameter andthe constructor template parameter. But, to answer your question, from [14.5.2p5]:

不能T用于类模板参数构造函数模板参数。但是,从[14.5.2p5]回答你的问题:

Because the explicit template argument list follows the function template name, and because conversion member function templates and constructor member function templates are called without using a function name, there is no way to provide an explicit template argument list for these function templates.

因为显式模板实参列表跟在函数模板名称之后,并且因为转换成员函数模板和构造函数成员函数模板是在不使用函数名称的情况下调用的,所以无法为这些函数模板提供显式模板实参列表。

Therefore, you cannot explicitly specify template arguments for constructor.

因此,您不能为构造函数显式指定模板参数。

回答by Cheers and hth. - Alf

You can't explicitly specify the template arguments for a constructor, because the constructor has no name on its own, and so there's no syntax for it.

您不能为构造函数显式指定模板参数,因为构造函数本身没有名称,因此没有语法。

But, you can ensure that correct template arguments are inferred, by

但是,你可以确保正确的模板参数被推断,由

  • casting actual arguments, and/or

  • introducing "artificial" extra arguments just to carry type information, if necessary, and/or

  • use a factory function.

  • 铸造实际参数,和/或

  • 如有必要,引入“人工”额外参数只是为了携带类型信息,和/或

  • 使用工厂函数。

For example, you can define

例如,您可以定义

template< class Type > struct TypeCarrier{ typedef Type T; };

struct MyClass
{
    template< class Type >
    MyClass( TypeCarrier< Type > ) { ... }
};

...
MyClass o( TypeCarrier<int>() );

But don't get carried away with such techniques.

但是不要被这些技术冲昏头脑。

Instead, if the apparent need to explicitly specify constructor template arguments pops up, think about whether the design is really sound?

相反,如果出现明显需要显式指定构造函数模板参数的情况,请考虑设计是否真的合理?

Perhaps you can use some simpler design if you reflect on what it’s for?

或许,如果你反省一下,这是你可以使用一些简单的设计

回答by David Hammen

You can explicitly specify the template arguments for your calls to foobecause those member functions foohave names -- and the template arguments are part of that name.

您可以为您的调用显式指定模板参数,foo因为这些成员函数foo具有名称——并且模板参数是该名称的一部分。

That doesn't work with constructors because a constructor has no name. You can't (directly) call a constructor. A constructor is of course called when you create an object, but the call is generated code.

这不适用于构造函数,因为构造函数没有名称。您不能(直接)调用构造函数。创建对象时当然会调用构造函数,但调用是生成的代码。