当我尝试在g++上编译下面的代码时,它可以工作,但在vs2015上失败,并显示消息:错误C2440:"initializing":无法从"const bool*"转换为"const bool(&([3]">
#include <iostream>
enum class Direction
{
RIGTH,
LEFT
};
struct Buffer
{
int catRigth = 4;
int catLeft = 8;
bool dogRigth[3] = {true, false, true};
bool dogLeft[3] = {false, true, false};
};
struct Bind
{
const int &cat;
const bool (&dog)[3];
Bind(const Buffer &buf, Direction direction) :
cat(direction == Direction::RIGTH ? buf.catRigth : buf.catLeft),
dog(direction == Direction::RIGTH ? buf.dogRigth : buf.dogLeft)
{
}
};
int main(int argc, char* argv[])
{
const Buffer buff;
Bind bindRigth(buff, Direction::RIGTH);
Bind bindLeft(buff, Direction::LEFT);
int catRigth = bindRigth.cat;
int catLeft = bindLeft.cat;
std::cout << catRigth << " " << catLeft;
}
它是一个标准的C++代码还是特定于gcc的行为?
MSVC不应该将其类型衰减为const bool *
:
5.16.4如果第二个和第三个操作数是相同值类别的glvalues并且具有相同的类型,则结果属于该类型和值类别,并且如果第二或第三个运算数是位字段,或者如果两者都是位字段则为位字段。
MSVC的一个变通方法可能是:
#include <utility>
const struct A {
bool a[3] = {false};
} obj;
template <class Lhs, class Rhs>
auto &&Conditional(const bool x, Lhs &&lhs, Rhs &&rhs) {
if (x)
return std::forward<Lhs>(lhs);
return std::forward<Rhs>(rhs);
}
int main(int argc, char* argv[]) {
const bool (&t)[3] = Conditional(true, obj.a, obj.a);
return 0;
}
PS:Conditional不是constexpr函数。
或:const bool (&t)[3] = *(true ? &obj.a : &obj.a);