C++ 模板参数场景

C++ 模板参数场景,c++,templates,C++,Templates,我有一个模板类MYVEC,它作为第二个模板参数传递给另一个模板类FOO template<class T> class MYVEC{ }; template<class T,class U> class FOO { }; main() { FOO<int, MYVEC<int>> obj; } 此外,我的编译器在尝试将其实例化为以下内容时不会抛出任何错误: FOO<int, MYVEC> obj; //I w

我有一个模板类
MYVEC
,它作为第二个模板参数传递给另一个模板类
FOO

template<class T>
class MYVEC{ };

template<class T,class U>
class FOO { };

main()
{
       FOO<int, MYVEC<int>> obj;
}
此外,我的编译器在尝试将其实例化为以下内容时不会抛出任何错误:

    FOO<int, MYVEC> obj; //I wonder what is the second template param type  here
FOO-obj//我想知道这里的第二个模板参数类型是什么
但这是一个编译器错误,尽管我希望它能工作:

    FOO<int, MYVEC<int>> obj;
FOO-obj;

模板参数有一个适用的小范围

假设你有一个管理资源的类。现在,您可以将它们存储在一个向量中,也可以存储在列表中,或者存储在您精心制作的某个异国情调的容器中通过模板参数作为类定义的一部分请求容器类型,您可以完全让用户选择

一些代码来说明这些差异

template<typename T> class MyResManagerv1
{
    std::vector<T> resources;
    // rest of your implementation details

    // rest of your public interface
};

MyResManagerv1<my_file_type> v1;

template<typename T> class MyResManagerv2
{
    std::list<T> resources;
    // rest of your implementation details

    // rest of your public interface
};

MyResManagerv2<my_file_type> v2;

template<typename T> class MyResManagerv3
{
    my_exotic_container<T> resources;
    // rest of your implementation details

    // rest of your public interface
};

MyResManagerv3<my_file_type> v3;

template<typename T, template<typename> class container> class MyResManagerv4
{
    container<T> resources;
    // rest of your implementation details

    // rest of your public interface
};

MyResManagerv4<my_file_type, std::vector> v4;
MyResManagerv4<my_file_type, std::list> v5;
MyResManagerv4<my_file_type, my_exotic_container> v6;
模板类MyResManagerv1
{
病媒资源;
//其余的实现细节
//公共界面的其余部分
};
MyResManagerv1;
模板类MyResManagerv2
{
std::列出资源;
//其余的实现细节
//公共界面的其余部分
};
MyResManagerv2;
模板类MyResManagerv3
{
我的异国情调容器资源;
//其余的实现细节
//公共界面的其余部分
};
MyResManagerv3 v3;
模板类MyResManagerv4
{
集装箱资源;
//其余的实现细节
//公共界面的其余部分
};
MyResManagerv4;
MyResManagerv4 v5;
MyResManagerv4 v6;

这个最终版本(仅限C++17,可以调整为与C++11和其他版本兼容)可以模拟任何其他版本(如果您向它们传递向量、列表或外来容器)。只要它们符合您的类所期望的接口。

切中要害的是,它本质上告诉您,
MYVEC
不是模板类型,因为该类型已完全实现。而当您使用
MYVEC
时,这是一种模板类型,因为它仍然需要一个模板参数

如果我可以用上述方式实例化
FOO
,那么为什么我需要模板参数语法

因为您可以防止以有问题的方式实例化
FOO
,例如

main()
{
    FOO<int, MYVEC<std::string>> obj2; // Probably fails to compile with a cryptic message
    FOO<int, MYVEC<short>> obj3; // Hopefully fails to compile, could easily have undefined behaviour
}
main()
{
FOO obj2;//可能无法使用神秘消息进行编译
FOO obj3;//可能无法编译,可能很容易有未定义的行为
}

C++的版本是什么?g++编译器4.83.你应该更新编译器。在这一点上,这是非常古老的。为什么您希望能够将类传递给需要类模板的对象?为什么将模板传递给需要模板的对象时会出现错误?请注意,这仅适用于
c++17
。您还缺少三个第一个版本的
。哎呀!我的坏消息是缺少类/结构。你能解释一下为什么这只适用于C++17吗?@super你指的是什么?“P必须至少和A一样专业(从C++17开始)”我指的是
std::vector
std::list
都有两个模板参数。第二个参数有一个默认值,但在
c++17
之前,这将无法与只有一个参数的模板参数匹配
main()
{
    FOO<int, MYVEC<std::string>> obj2; // Probably fails to compile with a cryptic message
    FOO<int, MYVEC<short>> obj3; // Hopefully fails to compile, could easily have undefined behaviour
}