问题陈述(用于教育目的):
- 实现适用于 STL 容器 vector
、stack
、queue
和 deque
的方法 printContainer。
我做了一个解决方案,但是我不喜欢它,因为代码太多。
我为解决问题所做的工作:
1。设计了通用函数,期望容器的统一接口(interface)用于操作:获取最后一个元素的值并从容器中删除该元素
template <typename T>
void printContainer(T container)
{
cout << " * * * * * * * * * * " << endl;
cout << " operator printContainer(T container). Stack, queue, priority queue"
<< endl;
cout << typeid(container).name() << endl;
while (!container.empty())
{
cout << top(container) << " ";
pop(container);
}
cout << endl;
cout << " * * * * * * * * * * * " << endl;
}
我为每个容器实现了允许提供统一接口(interface)的功能 (我想重构以下代码片段):
template <typename T>
typename vector<T>::value_type top(const vector<T>& v)
{
return v.back();
}
template <typename T, typename Base>
typename stack<T, Base>::value_type top(const stack<T, Base>& s)
{
return s.top();
}
template <typename T, typename Base>
typename queue<T, Base>::value_type top(const queue<T, Base>& q)
{
return q.front();
}
template <typename T, typename Base>
typename priority_queue<T, Base>::value_type top(const priority_queue<T,
Base>& pq)
{
return pq.top();
}
template <typename T>
void pop(vector<T>& v)
{
return v.pop_back();
}
template <typename T, typename Base>
void pop(stack<T, Base>& s)
{
return s.pop();
}
template <typename T, typename Base>
void pop(queue<T, Base>& q)
{
return q.pop();
}
template <typename T, typename Base>
void pop(priority_queue<T,Base>& pq)
{
return pq.pop();
}
我不想用这样的东西替换它:
template <typename T, typename Base, template<typename T, class Base,
class ALL = std::allocator<T>> class container>
typename container<T,Base>::value_type top(container<T,Base>& c)
{
if (typeid(container).name == typeid(vector<T,Base>))
return c.back();
if (typeid(container).name == typeid(queue<T,Base>))
return c.front();
else
return c.top();
}
template <typename T, typename Base, template<typename T, class Base,
class ALL = std::allocator<T>> class container>
typename container<T,Base>::value_type pop(container<T,Base>& c)
{
if (typeid(container).name == typeid(vector<T,Base>))
c.pop_back();
else
return c.pop();
}
但它不起作用,我收到如下错误:
Error 1 error C2784: 'container<T,Base>::value_type top(container<T,Base> &)' : could not deduce template argument for 'container<T,Base> &' from 'std::stack<_Ty>'
问题:
我应该在模板模板参数中添加邻接词来解决错误,也许我忽略了某些东西或存在逻辑错误。
无论如何,欢迎任何有用的信息。
提前致谢!
更新:
//这就是我尝试调用函数的方式
int arr[] = {1,2,3,4,5,6,7,8,9,0};
stack<int> s(deque<int>(arr, arr + sizeof(arr) / sizeof(arr[0])));;
queue<int> q(deque<int>(arr, arr + sizeof(arr) / sizeof(arr[0])));
priority_queue<int> pq(arr, arr + sizeof(arr) / sizeof(arr[0]));
printContainer(s);
printContainer(q);
printContainer(pq);
最佳答案
这个解决方案:
template <typename T, typename Base, template<typename T, class Base,
class ALL = std::allocator<T>> class container>
typename container<T,Base>::value_type top(container<T,Base>& c)
{
if (typeid(container).name == typeid(vector<T,Base>))
return c.back();
if (typeid(container).name == typeid(queue<T,Base>))
return c.front();
else
return c.top();
}
不会工作,因为 if()
实现了一个运行时选择,这意味着所有分支的代码都必须编译,即使恰好只有一个分支它们的计算结果为 true
,并且并非所有容器(例如 vector
)都提供函数 top()
。
考虑这个更简单的例子来解释:
struct X { void foo() { } };
struct Y { void bar() { } };
template<bool b, typename T>
void f(T t)
{
if (b)
{
t.foo();
}
else
{
t.bar();
}
}
int main()
{
X x;
f<true>(x); // ERROR! bar() is not a member function of X
Y y;
f<false>(y); // ERROR! foo() is not a member function of Y
}
在这里,我将编译时已知的 bool 模板参数传递给函数 f()
。如果输入的类型为 X
,我将传递 true
,因此支持名为 foo()
的成员函数;如果输入的类型为 Y
,我将传递 false
,因此支持名为 bar()
的成员函数。
即使选择在编译时已知的 bool 值上工作,语句本身也会在运行时执行。编译器首先必须编译整个函数,包括 if
语句的 false
分支。
您正在寻找的是某种 static if
construct ,不幸的是,它在 C++ 中不可用。
此处的传统解决方案基于重载,实际上看起来与您最初提供的解决方案类似。
关于c++ - 如何使用模板模板参数为该方法不需要通用接口(interface)的 STL 容器实现通用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15600198/