不使用模板参数使用模板类

4

我有一个使用Visual Studio 2008 C++开发的工程,其中包含一个模板类。该模板类在构造函数中采用模板化值,例如:

template< typename A >
struct Foo
{
    const A& a_;
    Foo( const A& a ) : a_( a ) { };
};

因此,我必须像这样构建这个类:
int myval = 0;
Foo< int > foo( myval );

当在构造函数中已经指定了int时,需要再次指定int作为模板参数似乎是多余的。我希望能以这种方式使用它:

Foo foo( myval );

现在我得到编译器错误:
error C2955: 'Foo' : use of class template requires template argument list

感谢您,PaulH。

我相信这是不可能的。我花了一天时间研究,发现有几个来源说它不是标准的,而且我也无法让MSVC或G++满意。 - totowtwo
3个回答

7

C++17修复了这个问题,引入了构造函数的模板参数推导

引用Herb Sutter的话:

[...]您现在可以只写pair p(2, 4.5);而不是pair<int,double> p(2, 4.5);或者auto p = make_pair(2, 4.5);。这非常好,包括它使许多“make”帮助程序过时。


6

如果您要命名类型,它必须是完整的类型(即Foo<int>而不仅仅是Foo)。

一个类可以有多个构造函数或者可能没有构造函数使用类模板的类型参数,因此对于所有类模板都无法使其工作(在我看来,有时能正常工作但有时不能会让人感到困惑)。

如果您不命名任何类型,您可以编写一个MakeFoo<T>()函数模板来构造Foo<T>,并使用函数模板实参推断:

template <typename A>
Foo<A> MakeFoo(const A& a) { return Foo<A>(a); }

这种模式在C++中很常见(例如,参见make_shared)。

但是,如果您想将返回的对象存储在变量中,则该变量仍需要具有类型。如果您能够切换到支持C++0x的编译器(如Visual C++ 2010),则可以使用auto。否则,您可以使用第三方解决方案,例如BOOST_AUTO或编写自己的代码(尽管这可能需要相当多的工作 (-: )。

使用auto,您的代码将如下所示:

auto foo(MakeFoo(myval));

4

类型推导仅适用于函数模板参数,而不是模板参数。

在C++0x中,您可以像这样做:

template<typename T>
Foo<T> CreateFoo(const T & a)
{
    return Foo<T>(a);
}

auto foo = CreateFoo(myval); //No need to write CreateFoo<int>(myval);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接