ADL在特定情况下不起作用
ADL does not work in the specific situation
我制作了如下的is_iterable模板,它检查自由函数begin/end是否可用(在ADL的上下文中)并返回正确的迭代器对象。(这是对循环范围内可迭代对象的要求)
#include <utility>
#include <iterator>
#include <type_traits>
#include <vector>
template <typename T>
typename std::add_rvalue_reference<T>::type declval(); // vs2010 does not support std::declval - workaround
template <bool b>
struct error_if_false;
template <>
struct error_if_false<true>
{
};
template<typename U>
struct is_input_iterator
{
enum {
value = std::is_base_of<
std::input_iterator_tag,
typename std::iterator_traits<U>::iterator_category
>::value
};
};
template<typename T>
struct is_iterable
{
typedef char yes;
typedef char (&no)[2];
template<typename U>
static auto check(U*) -> decltype(
error_if_false<
is_input_iterator<decltype(begin(declval<U>()))>::value
>(),
error_if_false<
is_input_iterator<decltype(end(declval<U>()))>::value
>(),
error_if_false<
std::is_same<
decltype(begin(declval<U>())),
decltype(end(declval<U>()))
>::value
>(),
yes()
);
template<typename>
static no check(...);
public:
static const bool value = (sizeof(check<typename std::decay<T>::type>(nullptr)) == sizeof(yes));
};
#include <cstdio>
void write(int a)
{
printf("%dn", a);
}
template<typename T>
typename std::enable_if<is_iterable<T>::value>::type write(const T& a)
{
for (auto i = begin(a), e = end(a); i != e; ++i) {
write(*i);
}
}
int main()
{
write(10);
std::vector<int> a;
a.push_back(1);
a.push_back(2);
a.push_back(3);
a.push_back(4);
write(a);
}
上面的代码在vs2010中完全按照预期工作,但在gcc中则不然。此外,当我放入一些名为"begin"的随机自由函数时,如下所示,它在vs2010中变得盈亏平衡。
int begin(int)
{
}
如何使代码正常工作?此外,任何改进"is_iterable"概念检查器的建议都将不胜感激。
added:"write"函数只是一个概念演示示例,请不要在上面投入宝贵的时间。(我知道这不是最好的代码:()需要注意的部分是ADL行为和"is_iterable"模板:)
将std::
添加到begin
/end
之后,您的代码将在gcc-4.6 下编译和运行
改进建议:将error_if_false
替换为enable_if
write(a);
应该像Jerry所说的那样通过运算符来定义。也许可以让它更加深思熟虑,这样你的代码就更干净了。
相关文章:
- G++ C++17 类模板参数推导在非常特殊的情况下不起作用
- EOF有更安全的替代方案吗?它在我的情况下不起作用
- 在特定情况下失败
- c++ 选择排序在特定情况下不起作用
- 为什么在这种情况下,前向声明不起作用?
- Qt TcpSocket::readyRead 在特定情况下未触发
- “overload_cast”在特定情况下失败
- 在特定情况下,static_cast和dynamic_cast的不同行为
- 在特定情况下,指针删除和铸造之间的关系不清楚
- LeetCode210.为什么我的代码在特定情况下是错误的
- 在特定情况下,班级驱动器
- 双右尖括号 (>>) 在特定情况下生成语法错误
- 为什么编译器不允许我在开关情况下使用变量?
- ADL在特定情况下不起作用
- C++11 在特定情况下避免冗余返回类型
- 在特定情况下跳出循环
- 子进程中的Execl仅在特定情况下工作
- 在 qt 中添加 += -std=c++11 QMAKE_CXXFLAGS 到 .pro 文件中不起作用(在 Linux
- 每当启动函数 game() 时,get(c) 第一次在循环中不起作用(在第 90 行中)。
- 为什么boost asio async_read_some在特定情况下不调用回调