模板模板参数的类型推导(C ++)

时间:2017-11-22 15:14:34

标签: c++ templates type-deduction

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

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模板参数不同的类型。

1 个答案:

答案 0 :(得分:1)

问题1:

  

[我]无法弄清楚为什么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<int, Bar<long>> 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