【发布时间】:2015-10-02 05:14:44
【问题描述】:
我正在开发一个通用遗传算法库,其中每个生物体的染色体是它在内存中的位表示。因此,例如,如果我想改变一个有机体,我会随机翻转对象本身的位。
起初,我尝试使用 C++ 标准库中的 bitset 类,但是,当转换回对象 T 时,我唯一的选择是使用 to_ullong 成员函数,这对于表示来说是个问题位数大于unsigned long long 的大小。
然后我决定为任何对象T 上的按位操作创建一个通用库,这样我就可以将这些操作直接应用于对象本身,而不是先将它们转换为bitset。
所以你可以看到我想要实现的目标,这是库中的一个函数:
template<typename T>
void flip(T& x, size_t const i)
{
x ^= 1 << i;
}
它在 GA 库中是这样使用的:
template<typename T>
void GeneticAlgorithm<T>::mutate(T& organism, double const rate)
{
std::random_device rd;
std::mt19937 mt(rd());
std::uniform_real_distribution<double> dist(0, 1);
for(size_t i = 0; i < m_nBits; ++i)
if(dist(mt) <= rate)
bit::flip(organism, i);
}
如果这能正常工作,那就太好了,但是现在我从 VC++ 2015 RC 编译器收到此错误消息:
严重性代码描述项目文件行错误 C2677 二进制“^”:否 找到了类型为“T”的全局运算符(或者没有可接受的 转换)遗传算法路径\遗传算法\遗传算法\BitManip.hpp 57
如果我为 ^ 更正此错误,我会为其他运算符获得更多信息。
我之前没有在我的代码中使用过位运算符,所以我猜这些运算符不应该与任何对象一起使用?如果是这样,我该如何解决这个问题?
【问题讨论】:
-
在 C++ 标准中定义的几乎所有bitwise operators 中,都以“运算符仅适用于整数或无范围枚举操作数”结束描述
-
C++ 和 C 也是不同的语言。不要在你的问题中标记 C,特别是因为你有模板和 C++ 标准库类。
-
您总是可以将有机体的地址或其他任何东西转换为 char* ,计算相关字节和其中的位偏移量,然后将 that 中的 that 位反转 字节。
-
我的直觉也是,flip() 应该是有机体的成员函数。也许您将来会使用与比特不同的东西(假设您想计算每个基因发生的翻转)。您将想要在不确切知道有机体如何处理它的情况下执行翻转。见鬼,你可能会调用一个人口众多的远程过程。
-
@FelipeCanever “我把 C 作为标签是因为我的问题与模板和标准库的按位运算更相关。” 它们仍然是不同的语言。您不能假设在 C 中适用的所有内容在 C++ 中也适用。运算符在两种语言中的行为并不总是相同。
标签: c++ bit-manipulation bit genetic-algorithm