如何转发声明C ++模板类?


99

给定一个类似下面的模板类:

template<typename Type, typename IDType=typename Type::IDType>
class Mappings
{
public:
    ...
    Type valueFor(const IDType& id) { // return value }
    ...
};

有人如何在头文件中转发声明此类?

Answers:


103

这是您的操作方式:

template<typename Type, typename IDType=typename Type::IDType>
class Mappings;

template<typename Type, typename IDType>
class Mappings
{
public:
    ...
    Type valueFor(const IDType& id) { // return value }
    ...
};

请注意,默认设置在前向声明中,而不在实际定义中。


可以向前声明在其定义中列出其默认值的类。看我的答案。
Elliott

我不同意。该标准说:“在同一范围内,两个不同的声明不应为模板参数提供默认参数”。而且我仅在第一个声明中没有发现任何关于默认值的信息。同样,带有前向声明和定义中默认值的代码也可以成功编译并运行。您确定要求什么吗?您能提供标准的报价吗?
olek stolar

@Elliott看来这是真的。标准[17.1.9]说:可以在模板声明中指定默认模板参数。” 不是必须的,但可能是。因此,我不明白为什么其他答案声称它应该在第一个声明中。
olek stolar

在定义中使用默认值似乎更加方便。
olek stolar

8

您只能为模板的第一个声明声明模板的默认参数。如果要允许用户转发声明类模板,则应提供转发标头。如果您想使用默认值来声明其他人的类模板,那您真不走运!


可以向前声明在其定义中列出其默认值的类。看我的答案。
Elliott

我不同意。该标准说:“在同一范围内,两个不同的声明不应为模板参数提供默认参数”。而且我仅在第一个声明中没有发现任何关于默认值的信息。同样,带有前向声明和定义中默认值的代码也可以成功编译并运行。您确定要求什么吗?您能提供标准的报价吗?
olek stolar

3

可以声明一个模板化的类,其定义指出默认参数,但是任何时候引用该类时,都必须包括其所有参数,直到引入定义为止。

例如。让我们在std::vector不包含它的情况下使用它(其第二个参数std::vector定义为默认值):

namespace std
{
    template<typename, typename>
    class vector;
}

#include <iostream>

template <typename S, typename T>
void Foo (const std::vector<S,T> & vector)
{
    std::cout << "do vector stuff, eg., display size = "
        << vector.size() << std::endl;
}

template <typename T>
void Foo (const T & t)
{
    std::cout << "do non-vector stuff..." << std::endl;
}

然后我们可以不包含向量就使用它,例如:

int main()
{
    Foo(3);
}

我们可以将其与一起使用 std::vector,例如:

#include <vector>

// Now the compiler understands how to handle
// std::vector with one argument
// (making use of its default argument)

int main()
{
    Foo(std::vector<int>(3));
}

我没有检查的标准,但在这个作品clang/ gcc-std=c++98高达-std=c++17,所以如果它不是一个正式的标准,然后它看起来是如此非官方。


也许您忘记了空的尖括号Foo<> foo;
olek stolar

@ OleksijPlotnyc'kyj你是对的。谢谢。我已删除了该添加项。
Elliott
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.