【发布时间】:2021-09-07 10:03:57
【问题描述】:
tl;博士
当我尝试编译此代码时,Visual Studio 会为 static_assert 抛出一个编译时错误,不管它应该是什么,然后还会为唯一应该的那个抛出一个“活动错误”。这是我的代码或 Visual Studio 的问题?
Visual Studio 版本
Microsoft Visual Studio 社区 2019
版本 16.10.2
#include <memory>
struct Node {};
struct A : Node {};
struct B : Node {};
#define cast_to_A(ptr) ([&] () { \
static_assert( \
std::is_same<std::shared_ptr<Node>, decltype(ptr)>::value, \
"Cannot cast to an A pointer." \
); \
return std::static_pointer_cast<A>(ptr); \
})()
#define cast_to_B(ptr) ([&] () { \
static_assert( \
std::is_same<std::shared_ptr<Node>, decltype(ptr)>::value, \
"Cannot cast to a B pointer." \
); \
return std::static_pointer_cast<B>(ptr); \
})()
int main() {
auto a = std::make_shared<A>();
auto b = std::make_shared<B>();
auto aAsNode = std::static_pointer_cast<Node>(a);
auto bAsNode = std::static_pointer_cast<Node>(b);
auto a1 = cast_to_A(aAsNode); // Expected: No error, Actual: "Cannot cast to an A pointer."
auto b1 = cast_to_B(bAsNode); // Expected: No error, Actual: "Cannot cast to an B pointer."
auto badCast = cast_to_A(b); // Expected & Actual: "Cannot cast to an A pointer."
return 0;
}
上下文
在一个个人项目中,我有一个 node 结构,一堆子结构从中继承。在整个程序中,我从std::shared_ptr<Node> 转换为std::shared_ptr<Child>,反之亦然,使用std::static_pointer_cast。在我的程序的某个地方,我有编译时错误,我正试图从一个兄弟指针转换为另一个。但是,该错误归因于 std::static_pointer_cast(
碰巧的是,我的结构代码是由我编写的 python 脚本程序生成的。我尝试的解决方案是为每个结构生成一个宏(就像在玩具示例中看到的那样),然后我只是做了一个正则表达式搜索/替换,用适当的宏替换我所有的 std::static_pointer_cast 调用。
我遇到的问题是在上面的玩具示例中重新创建的。 Visual Studio 在宏“调用”下放了一条红线,我预计会失败(所以我现在实际上发现了这个错误),但是对于宏的每次使用它也会从 static_assert 引发编译时错误,即使(据我所知)它不应该失败。不过,它并没有在这些“调用”下添加红线,所以我不确定这是否是 Visual Studio 错误。
在网上环顾四周,std::is_same 可以非常挑剔什么算作同一类型。作为 marco 参数给出的变量 get 通过引用传递给 static_assert (因为它通过 lambda 的 [&] 捕获),所以我想知道这是否把它扔掉了。但是我想不出任何方法来调整类型以使其正常工作。
提前感谢您的帮助!非常感谢任何指针或提示!
【问题讨论】:
-
由于您通过引用将参数传递给 lambda,我认为您可能需要使用 remove_reference,
decltype(std::remove_reference(ptr)) -
@1201ProgramAlarm 你说得对!语法略有不同,但我让它工作了,现在只有糟糕的演员才会抛出错误。语法是
std::remove_reference<decltype(ptr)>::type。非常感谢您的帮助!
标签: c++ visual-studio compiler-errors macros static-assert