C++模板名称在没有模板参数的情况下使用

6

我之前一直在使用"const ObjArray&"作为ObjArray模板的参数,但并没有仔细思考过这个问题。看起来它能够正常运行,但当我重新阅读时感觉有些不对劲。应该是"const ObjArray<T> &"才对吧?在没有指定参数的情况下引用模板名称是否可行?它之所以能够正常工作,是因为被声明为内联函数,编译器自动推断了T的值吗?

template <class T>
class ObjArray : public BArray
{
public:
    inline ObjArray() :
        BArray(sizeof(T), NULL)
    {
    }

    inline ObjArray(const ObjArray& src) :
        BArray(sizeof(T), NULL)
    {
        copyFrom((ObjArray&)src);
    }

    inline ObjArray(ObjArray& src) :
        BArray(sizeof(T), NULL)
    {
        copyFrom(src);
    }
    ...
};

9
在类定义内部这样做是可以的。 - juanchopanza
2
类名在其自身定义中是可见的。这被称为“类名注入”。对于类模板,当模板名称后面没有跟随模板参数时,被视为注入的类名。因此,在ObjArray的定义中仅使用ObjArray是可以的。 - n. m.
2个回答

5
不,那种用法是正确的:在类模板中,类名指代该模板的实例,因此不需要使用模板参数。
template<typename T>
struct foo
{
    foo( const foo& ); //Copy ctor. foo is the same as foo<T>
};

这种行为在标准文档14.6.1 局部声明名称中有明确定义(强调是我的):

14.6.1 局部声明名称 [temp.local]
类模板和普通类一样都有一个被注入的类名(第9条)。 这个被注入的类名可以带或不带模板参数列表。当它不带模板参数列表时,等同于将被注入的类名后面跟着封闭在<>中的类模板的模板参数。当它带有模板参数列表时,它指的是指定的类模板特化,这可能是当前特化或另一个特化。

请注意,语法只是当前模板实例的别名。如果您需要使用其他参数相同的模板,则需要使用经典语法显式地指定它。例如:

template<typename U>
operator foo<U>() const //Implicit conversion to other instance of the template
{
    return ...;
}

1

是的,这是正确的C++语法。关于你提出的内联问题,你可以在类声明外部这样写:

template<typename T>
foo<T>::foo(const foo&)
{}

即使不指定模板参数,代码也是正确的。请注意,只有第一个foo明确地带有模板参数。一旦它被指定,上下文就完全定义了,现在你可以将foo用作一个完全合法的类名,因此foo参数将自动引用foo<T>


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