我很困惑为什么下面的代码被编译器拒绝了。有些帮忙吗?
template<template<template<class> class> class Ptr,
template<class> class Container, class T>
inline void print(Ptr<Container<T>> l) {
std::cout << '[';
for (auto it = l->begin(); it != l->end() - 1; ++it) {
std::cout << *it << ", ";
}
std::cout << l->back() << ']' << std::endl;
}
答案 0 :(得分:2)
我可以想到以下两种方法来解决问题。
template <template <template <class> class> class Ptr,
template<class> class Container, class T>
inline void print(Ptr<Container> l) {
// ^^^ Not Ptr<Container<T>>
std::cout << '[';
for (auto it = l->begin(); it != l->end() - 1; ++it) {
std::cout << *it << ", ";
}
std::cout << l->back() << ']' << std::endl;
}
或
template <template<class> class Ptr,
// One less level of template for Ptr
template<class> class Container, class T>
inline void print(Ptr<Container<T>> l) {
// Containe<T> is a class
std::cout << '[';
for (auto it = l->begin(); it != l->end() - 1; ++it) {
std::cout << *it << ", ";
}
std::cout << l->back() << ']' << std::endl;
}
查看您的代码,不清楚哪一个适合您。
<强>更新强>
以下代码不起作用
#include <vector>
#include <memory>
template<template<class> class Ptr, template<class> class Container, class T>
inline void f(Ptr<Container<T>> p) {}
int main() {
f(std::make_shared<std::vector<int>>());
}
因为std::vector
定义为:
template<
class T,
class Allocator = std::allocator<T>
> class vector;
不是
template<
class T,
> class vector;
这有效:
template<template<class> class Ptr, template<class> class Container, class T>
inline void f(Ptr<Container<T>> p) {}
template <typename T> using MyVector = std::vector<T>;
int main() {
f<std::shared_ptr, MyVector, int>(std::make_shared<MyVector<int>>());
}
这也有效:
template<template<class> class Ptr, template<class> class Container, class T>
inline void f(Ptr<Container<T>> p) {}
template <typename T> struct Foo {};
int main() {
f(std::make_shared<Foo<int>>());
}
答案 1 :(得分:2)
我对@RSahu的回答是否有效以及是否解决问题感到困惑。
但是,受其启发,我得到了以下解决方案。这简单地利用了类模板类可以是可变参数的事实。因此,例如现在与std::vector<T, A>
或其他具有更多或更少模板参数的类(容器hopefuly)兼容。事实上,使用Ptr
参数执行相同操作非常有用,因此它与std::unique_ptr
兼容,可以获得比std::shared_ptr
更多的模板参数。
http://coliru.stacked-crooked.com/a/40d43526ed77eb9d
#include <iostream>
#include <vector>
#include <memory>
template<template<class...> class Ptr, template<class...> class Container, class T>
inline void f(Ptr<Container<T>> p) {
std::cout << "bla" << std::endl;
}
int main() {
f(std::make_shared<std::vector<int>>());
}
注意:话虽如此,我认为有更好的方法来约束参数类型而不是强制模式。
例如,这可能是另一种选择:
template<class PtrContainerT, typename = decltype( std::declval<PtrContainerT>()->back())> //probably pretty much constrains the intended use
inline void f(PtrContainerT&& p) {
using T = typename PtrContainerT::element_type::value_type; //in case you need to know T
std::cout << "bla" << std::endl;
}
http://coliru.stacked-crooked.com/a/fbe43aab94364764
甚至更重要(尽管不是100%相当):
template<class PtrContainerT, typename T = typename PtrContainerT::element_type::value_type> //probably pretty much constrains the intended use
inline void f(PtrContainerT&& p) {
std::cout << "bla" << std::endl;
}
如有必要,请使用std::decay<PtrContainerT>::...etc
。