Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从类模板中排除类型_C++_Templates - Fatal编程技术网

C++ 从类模板中排除类型

C++ 从类模板中排除类型,c++,templates,C++,Templates,我目前在stack中遇到问题,将我的一个模板类弄乱了。 问题是像pusk\u back、begin或end这样的方法不能用于该类型。 因此,我在这里的目标是防止使用stack实例化contain,或者添加一个条件,防止stack实例访问代码的这些部分。 下面是类的外观: template<typename T, template <typename...> typename U> class contain { public: contain()

我目前在
stack
中遇到问题,将我的一个模板类弄乱了。
问题是像
pusk\u back
begin
end
这样的方法不能用于该类型。
因此,我在这里的目标是防止使用
stack
实例化contain,或者添加一个条件,防止
stack
实例访问代码的这些部分。
下面是
的外观:

template<typename T, template <typename...> typename U>
class contain {
    public:
        contain() : _container()
        {
        }
        ~contain()
        {
        }
        void push(T const&data)
        {
            this->_container.push_back(data);
        }
        void aff()
        {
            std::for_each(_container.begin(), _container.end(),
            [](T &var) {::aff(var);});
        }
        void add()
        {
            std::for_each(_container.begin(), _container.end(),
            [](T &var) {::add(var);});
        }
    private:
        U<T> _container;
};
模板
类包含{
公众:
contain():_container()
{
}
~contain()
{
}
无效推送(T常量和数据)
{
此->\u容器。将\u推回(数据);
}
无效aff()
{
std::for_each(_container.begin(),_container.end(),
[](T&var){::aff(var);};
}
void add()
{
std::for_each(_container.begin(),_container.end(),
[](T&var){::添加(var);};
}
私人:
U_容器;
};

我试图专门化模板,但无法找到语法,也无法在运行时检查变量的类型。

我必须承认,
模板
对我来说仍然有点像黑魔法。我已经在各种情况下成功地使用了模板专门化(如果我没有更好的想法的话),但从未使用过模板参数。所以,我试着

当我尝试使用coliru(编译器
g++(GCC)8.1.0
)时,我从
-std=c++11
开始,很快就出现了一些可怕的错误。幸运的是,还有一个切换到
-std=c++17
的提示。我做到了,事情马上变得好多了。我大致记得C++11中不支持模板参数。只要看一眼
cppreference
就证明我是对的:

模板<参数列表>类型名(C++17)|类名(可选)(1)
模板<参数列表>类型名(C++17)|类名(可选)=默认值(2)
模板<参数列表>类型名(C++17)|类。。。名称(可选)(3)(自C++11起)

1) 具有可选名称的模板参数。
2) 具有可选名称和默认值的模板参数。
3) 具有可选名称的模板参数包。

澄清了这一点后,我加入了OPs示例代码的一部分,并为
模板添加了部分专门化

  • 左键为第一个参数
  • std::stack
    专门化第二个参数
实际上,这与具有类型或值参数的模板的专用化方式没有太大区别

cppreference
对此有一篇文章,但是使用这个词作为搜索关键词,应该会有很多书籍和教程的点击率。(我记得我曾经从上面提到过的C++模板中学习过的书。当然,当然。) 因此,这里是我的小样本来证明这一点:

#include <iostream>
#include <stack>
#include <vector>

template<typename T, template <typename...> typename U>
class ContainerT {
  private:
    U<T> _container;
  public:
    ContainerT(): _container() { }
    ~ContainerT() = default;
    ContainerT(const ContainerT&) = default;
    ContainerT& operator=(const ContainerT&) = default;

    bool empty() const { return _container.empty(); }
    void push(const T &data) { _container.push_back(data); }
    T pop()
    {
      const T data = _container.back();
      _container.pop_back();
      return data;
    }
};

template<typename T>
class ContainerT<T, std::stack> {
  private:
    std::stack<T> _container;
  public:
    ContainerT(): _container() { }
    ~ContainerT() = default;
    ContainerT(const ContainerT&) = default;
    ContainerT& operator=(const ContainerT&) = default;

    bool empty() const { return _container.empty(); }
    void push(const T &data) { _container.push(data); }
    T pop()
    {
      const T data = _container.top();
      _container.pop();
      return data;
    }
};

#define DEBUG(...) std::cout << #__VA_ARGS__ << ";\n"; __VA_ARGS__ 

int main()
{
  // for std::vector
  DEBUG(ContainerT<int, std::vector> vec);
  DEBUG(vec.push(1); vec.push(2); vec.push(3));
  DEBUG(while (!vec.empty()) std::cout << vec.pop() << '\n');
  // for std::stack
  DEBUG(ContainerT<int, std::stack> stk);
  DEBUG(stk.push(1); stk.push(2); stk.push(3));
  DEBUG(while (!stk.empty()) std::cout << stk.pop() << '\n');
  // done
  return 0;
}

你的目标是什么?要防止
包含
堆栈实例化
?如果是,你已经有了,不是吗?因为模板无法实例化,正如您所说。或者您只是想摆脱不适用于
堆栈的函数吗?你想做什么?我想你跳过了问题中的一些步骤。stack是如何参与的?您正在尝试使用std::stack作为此容器的适配器吗?它明显违反了SequenceContainer的要求请参见@LightnessRacesinOrbit我已经明确了我的目标,我承认这个问题不好formulated@KennyOstrom实际上,我试图将stack从template的
U
参数中排除如果您不希望模板为某个类实例化,您可以专门化该类的模板。因此,模板专门化可以提供另一种实现。例如,使用
std::vector
(尽管这被认为是“不太幸运的想法”)。