【问题标题】:Type deduction for template template parameters (C++)模板模板参数的类型推导(C++)
【发布时间】:2017-11-22 15:14:34
【问题描述】:

使用下面的代码,我遇到了编译器错误:

type/value mismatch at argument 1 in template parameter list for 'template<class _Tp> class std::shared_ptr' std::shared_ptr<T> shared_pointer; ^ ../test/main.cpp:16:22: note: expected a type, got 'T'

不明白为什么T 没有正确推断为shared_pointer

template<typename K>
class Bar{
    K k;
};

template<template<typename> class T>
class Foo{
public:
    std::shared_ptr<T> shared_pointer;
};


int main(void)
{
    Foo<Bar<std::string>> foo;
}

更新: 另一个例子:

template<typename TObject, template<TObject> class TBuffer>
class BaseGrabber {

public:
    virtual void run(std::shared_ptr<TBuffer>){};
};

当有人写类似的东西时,我想强制编译器出错

BaseGrabber<int, Bar<long>> grabber;

所以Bar 从来没有专门使用不同于第一个BaseGrabber 模板参数的类型。

【问题讨论】:

  • template&lt;typename&gt;template&lt;template&lt;typename&gt; class T&gt; 中的作用是什么?
  • 错误消息已损坏:这是预期类型与 T模板 之间的不匹配。 IOW,std::shared_ptr&lt;T&lt;something&gt;&gt; 会工作。
  • @AlgirdasPreidžius 的意思是(我想)一旦您删除 template&lt;typename&gt; 并将 Foo` 定义为 template&lt;class T&gt;,一切都会正常工作。
  • 我正在使用多个模板参数,当有人尝试使用不同模板类型实例化模板类时,我想强制编译器出错。更新的问题。
  • @AlanKazbekov 然后你可以将它用作BaseGrabber&lt;int, Bar&gt;,并使用模板参数TObject 实例化BaseGrabber 中的模板。

标签: c++ templates type-deduction


【解决方案1】:

问题 1:

[I] 无法弄清楚为什么 T 没有正确推断为 shared_pointer

template<template<typename> class T>
class Foo{
public:
    std::shared_ptr<T> shared_pointer;
};

答案: T 不能推导出为 shared_ptr,因为 T 是模板类型,并且您没有给它任何模板参数。只需将其缩减为 class T 即可:

template<class T>
class Foo{
public:
    std::shared_ptr<T> shared_pointer;
};

问题 2:

我想在有人写以下内容时强制编译器出错:
BaseGrabber&lt;int, Bar&lt;long&gt;&gt; grabber;

答案: 我们将为BaseGrabber 编写一个空的主特化,然后在第二个参数使用与第一个参数相同的模板参数类型时将其特化:

template<class T, class U>
class BaseGrabber{
    static_assert(sizeof(T) == 0, "Template argument is not correct");
};

template<class T, template<class> class U>
class BaseGrabber<T, U<T>> {
public:
    virtual void run(std::shared_ptr<T>){};
}

像这样测试它:

int main()
{
    Foo<Bar<std::string>> foo;
    //BaseGrabber<int, Bar<long>> grabber; // compiler error
    BaseGrabber<int, Bar<int>> grabber;
}

Live Demo

【讨论】:

  • 感谢#1,感谢#2!刚刚为自己发现了static_assert(sizeof(T) == 0, "..."); 是一种常见做法!
猜你喜欢
  • 2020-07-09
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 2011-10-07
  • 2018-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多