C++中一个模板函数中使用的类的不常见函数
uncommon function of classes used in one template function in C++
>我将在以下代码中传递"堆栈"和"队列"作为模板类型。
知道 .front() 和 .top() 不是"queue"和"stack"之间的通用函数,我使用 "if" 进行检查。
但它仍然无法编译。(错误 C2039:"top"不是 std::queue<_Ty> 的成员)
有没有办法解决这个问题?
template<typename T>
void push_pop(string *str, T *containers){
string s = typeid(containers).name();
if(s[11]=='q'){
str->push_back(containers->front()); containers->pop();
}else{
str->push_back(containers->top()); containers->pop();
}
}
我知道我可以使用函数重载,但我想使用模板解决这个问题。
感谢您的回答!
问题是编译器必须编译检查的两个分支,并且它不能为队列编译container.top()
,也不能为堆栈编译container.front()
。
您必须为std::queue
和std::stack
实现单独的函数模板:
template<typename V, typename C>
void push_pop(std::string &str, std::stack<V, C> &container) {
str.push_back(container.top());
container.pop();
}
template<typename V, typename C>
void push_pop(std::string &str, std::queue<V, C> &container) {
str.push_back(container.front());
container.pop();
}
可以(我建议这样做)仅对相关部分执行此操作:
template<typename V, typename C>
V const &first_element(std::stack<V, C> const &container) {
return container.top();
}
template<typename V, typename C>
V const &first_element(std::queue<V, C> const &container) {
return container.front();
}
template<typename T>
void push_pop(std::string &str, T &container) {
str.push_back(first_element(container));
container.pop();
}
(未经测试) - 我使用如下所示的宏:
#define FUNC_TEST(func)
template<typename T>
struct has_##func
{
template <typename _1> static std::true_type test(decltype(&_1::func)*);
template <typename > static std::false_type test(...);
static const bool value = decltype(test<T>(0))::value;
}
然后,对于我需要测试的所有函数,我将使用宏来生成测试代码,例如:
FUNC_TEST(top);
FUNC_TEST(front);
然后,我将定义几个帮助程序函数来处理实际的回推:
// If the type supports top(), then the first variant is enabled and selected
template <typename F>
inline enable_fn<has_top<F>, void> use_top(F* o, std::string* dest)
{ dest->push_back(o->top()); }
template <typename F>
inline disable_fn<has_top<F>, void> use_top(F*, std::string*)
{ }
// If the type supports front(), the first variant is selected from below automatically
template <typename F>
inline enable_fn<has_front<F>> use_front(F* o, std::string* dest)
{ dest->push_back(o->front()); }
template <typename F>
inline disable_fn<has_front<F>> use_front(F*, std::string*)
{ }
调用时,只需调用两个变体,编译器将根据 SFINAE 测试选择适当的操作。
template<typename T>
void push_pop(string *str, T *container){
use_top(container, str);
use_front(container, str);
container->pop();
}
看起来我们正在调用top()
和front()
,但根据容器是否支持top()
或front()
将编译出一个或另一个函数调用。如果类型 T
同时支持 front()
和 top()
,这有点问题,但我会把它留给你一个练习来修复......
(注意:您需要enable_fn
看起来像:
template <typename T>
using type_of = typename T::type;
template <typename C, typename R = void>
using enable_fn = type_of<std::enable_if<C::value, R>>;
我会把disable_fn
留给你做练习...
代码的问题在于您正在尝试进行运行时检查,这导致容器类同时提供 top() 和 front() 的要求。正如@Wintermute所建议的那样,解决此问题的一种方法是使用模板专用化。如果你想要更花哨和通用的方式,你可以使用 SFINAE 方法,它与 C++11 相结合,提供干净漂亮的代码。假设我们只有两种可能的容器 - 提供 front() 或 top() 方法(添加新类型的函数非常容易):
template<typename container>
auto get_from_container(container* c, int) -> decltype(std::declval<container>().front(), typename container::value_type()) {
return c->front();
}
template<typename container>
typename container::value_type get_from_container(container* c, long) {
return c->top();
}
template<typename T>
void push_pop(string *str, T *containers){
str->push_back(get_from_container(containers, 0)); containers->pop();
}
请注意 get_from_container 中的第二个类型参数 - 需要使用 top() 方法隐藏"默认"实现(如此处所述)
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 为什么虚函数不能是静态的和全局的?
- g++ 说函数不存在,即使包含正确的标头
- 当调用switch语句中的函数时(即使函数不包含循环),似乎是永不结束的循环的问题
- C++Brute Force攻击函数不会返回结果
- 仅包含可移动 std::map 的类的移动构造函数不起作用
- 为什么我的数组双精度函数不起作用?
- std::unordered_map析构函数不释放内存?
- 函数不接受 X 参数,函数使用默认参数
- 为什么用户定义的函数不按照给定的顺序对相同长度的元素进行排序?
- 函数签名与调用的函数不匹配,常量字符[]和字符*之间的区别?
- 从函数(不抛出函数)返回异常以进行消息格式化?
- 如何修复加载图标()函数不显示图标?
- 被覆盖的函数不会反映在基类中,这是正常行为吗?
- 为什么这个噪声函数不处理否定参数?
- C++ - 空模板类构造函数不初始化值
- 为什么在指向对象的迭代器上调用函数不允许我更改对象本身?
- 为什么这些函数不衰减到函数指针?
- 为什么从另一个构造函数内部调用C++构造函数不修改类变量?
- C++中一个模板函数中使用的类的不常见函数