当从实际存储类型到请求类型的隐式转换可能时,为什么std::any_cast抛出std::bad_any_cast异常?
例如:
std::any a = 10; // holds an int now
auto b = std::any_cast<long>(a); // throws bad_any_cast exception
Run Code Online (Sandbox Code Playgroud)
为什么这是不允许的,是否有允许隐式转换的解决方法(如果std::any保存的确切类型未知)?
假设我有一个类型的对象
std::map<std::string, std::tuple<int, float>> data;
Run Code Online (Sandbox Code Playgroud)
是否可以以嵌套的方式访问元素类型(例如,当在ranged for循环中使用时)
for (auto [str, [my_int, my_float]] : data) /* do something */
Run Code Online (Sandbox Code Playgroud) 我目前正致力于增强现实游戏.游戏使用的控制器(我在这里谈论的是物理输入设备)是单色的,长方形的纸片.我必须在摄像机的捕获流中检测该矩形的位置,旋转和大小.检测应在尺度上不变,并且在沿X和Y轴旋转时不变.
在用户将纸张移开或朝向相机移动的情况下,需要比例不变性.我不需要知道矩形的距离,因此尺度不变性转换为尺寸不变性.
如果用户沿其局部X和/或Y轴倾斜矩形,则需要旋转不变性.这种旋转将纸张的形状从矩形变为梯形.在这种情况下,面向对象的边界框可用于测量纸张的尺寸.
开始时有一个校准步骤.窗口显示摄像机源,用户必须单击矩形.单击时,鼠标指向的像素颜色将作为参考颜色.帧被转换为HSV颜色空间以改善颜色区分.我有6个滑块可以调整每个通道的上限和下限.这些阈值用于对图像进行二值化(使用opencv inRange函数).
在那之后,我正在侵蚀和扩展二进制图像以消除噪声并联合nerby块(使用opencv erode和dilate函数).
下一步是findContours在二进制图像中查找轮廓(使用opencv 函数).这些轮廓用于检测最小的方向矩形(使用opencv minAreaRect函数).作为最终结果,我正在使用面积最大的矩形.
该程序的简短结论:
您可能已经注意到,我没有利用有关纸张实际形状的知识,仅仅因为我不知道如何正确使用这些信息.
我也考虑过使用opencv的跟踪算法.但有三个原因使我无法使用它们:
这是一个 - 相对 - 好的捕获(侵蚀和扩张后的二进制图像)

如何提高检测效果,尤其是更能抵抗照明变化?
以下是一些用于测试的原始图像.
你不能只使用更厚的材料吗?
是的,我可以而且我已经做过了(不幸的是我现在无法访问这些内容).但问题仍然存在.即使我使用像cartboard这样的材料.它不像纸一样容易弯曲,但仍然可以弯曲它.
你如何获得矩形的大小,旋转和位置?opencv
的minAreaRect功能返回一个RotatedRect对象.该对象包含我需要的所有数据.
注意
由于矩形是单色的,因此无法区分顶部和底部或左右.这意味着旋转始终在[0, 180]我的目的范围内完全正常.矩形两边的比例总是如此w:h > 2:1.如果矩形是方形,则旋转范围将变为[0, 90],但这可以认为是无关紧要的.
正如评论中所建议的那样,我将尝试使用直方图均衡来减少亮度问题并查看ORB,SURF和SIFT.
我会更新进展情况.
我已经创建了一个函数,它将多个较小的值连接成一个较大的值,同时保留值的bianry表示(例如,int argb从多个构建一个unsigned char r, g, b, a).我知道我也可以通过改变价值来实现这一点,但这不是这个问题的问题.
但是,如果我使用该函数实际从这些值生成一个整数,msvc会抛出编译器错误:
error C3615: constexpr function 'Color::operator int' cannot result in a constant expression
note: failure was caused by call of undefined function or one not declared 'constexpr'
note: see usage of '<lambda_dcb9c20fcc2050e56c066522a838749d>::operator ()'
Run Code Online (Sandbox Code Playgroud)
这是一个完整的样本.Clang和gcc编译代码但msvc拒绝:
#include <type_traits>
#include <memory>
namespace detail
{
template <typename From, typename To, size_t Size>
union binary_fusion_helper
{
const From from[Size];
const To to;
};
template <typename To, typename Arg, typename ...Args, typename = std::enable_if_t<(... …Run Code Online (Sandbox Code Playgroud) 使用 C# 8 的可空引用类型,我们可以编写(对于引用类型):
T x = ...;
T? y = x;
Run Code Online (Sandbox Code Playgroud)
但是,我无法理解多维和锯齿状数组的转换规则。
string[][] a = new string[1][];
string?[]?[] b = new string[1][];
string?[]?[]? c = new string[1][];
string?[,][] d = new string[1,2][];
string?[,][]? e = new string[1,2][];
string?[,]?[] f = new string[1,2][]; // compiler error
Run Code Online (Sandbox Code Playgroud)
最后一个例子给了我
错误 CS0029:无法将类型 'string[ , ][]' 隐式转换为 'string?[ , ]?[]'
既然它适用于锯齿状数组(请参阅 参考资料b),为什么它不适用于多维数组呢?
R# 还告诉我
'c' 可以声明为不可空
string?[]?[]? c = new string[1][];
// ^ redundant
Run Code Online (Sandbox Code Playgroud)
我知道编译器可以证明它c本身不为空,但我很困惑第三个?是多余的。鉴于锯齿状数组是从左到右创建的(即new int[2][]而不是 …
c# jagged-arrays multidimensional-array nullable-reference-types
我编写了一个小函数模板,它将新容器中的不同容器连接起来:
#include <vector>
#include <unordered_set>
#include <string>
#include <iostream>
#include <iterator>
namespace impl
{
template <typename OutIterator, typename Container, typename ...Containers>
void join(OutIterator iterator, const Container& container, const Containers& ...containers)
{
for (const auto& item : container)
*iterator++ = item;
join(iterator, containers...); // gcc and clang cannot resolve this call
}
template <typename OutIterator, typename Container>
void join(OutIterator iterator, const Container& container)
{
for (const auto& item : container)
*iterator++ = item;
}
}
template <typename OutContainer, typename ...Containers>
OutContainer …Run Code Online (Sandbox Code Playgroud) 鉴于代码
struct A {};
auto obj = new A;
std::vector<unsigned char> buffer;
buffer.resize(sizeof(obj));
std::memcpy(buffer.data(), &obj, sizeof(obj)); // this copies the pointer, not the object!
// ...
auto ptr = *reinterpret_cast<A**>(buffer.data()); // is this UB?
delete ptr;
Run Code Online (Sandbox Code Playgroud)
reinterpret_cast在这种情况下是使用UB 吗?我会说是的,因为memcpy没有开始实例的生命周期,因此违反了严格的别名规则(这就是为什么std::bit_cast被添加到 C++20)。
如果我用另一个memcpy(读取指针)替换强制转换,程序会被很好地定义吗?
给定结构 S1:
unsafe readonly struct S1
{
public readonly int A1, A2;
public readonly int* B;
public S1(int a1, int a2, int* b)
{
A1 = a1;
A2 = a2;
B = b;
}
}
Run Code Online (Sandbox Code Playgroud)
和一个平等测试:
int x = 10;
var a = new S1(1, 2, &x);
var b = new S1(1, 2, &x);
var areEqual = Equals(a, b); // true
Run Code Online (Sandbox Code Playgroud)
areEqual 正如预期的那样,评估为 true。
Now lets slightly change our struct to S2 (replacing the pointer with a string):
unsafe readonly …Run Code Online (Sandbox Code Playgroud) 是否有理由(除了因为标准这么说)为什么不允许使用以下代码?
struct Foo
{
~Foo() && {}
~Foo() & {}
};
Run Code Online (Sandbox Code Playgroud)
我知道这是非法的,但我想知道为什么。
我在考虑避免未命名实例问题,即在使用保护对象时,例如:
void do_something()
{
std::lock_guard{my_mutex};
// some synchronized operation
}
Run Code Online (Sandbox Code Playgroud)
这是合法的代码,但显然很容易出错,因为锁保护会在构造后立即销毁,因为它是一个临时(未命名)对象。
我正打算做这样的事情
struct Foo
{
~Foo() && = delete;
~Foo() & = default;
};
Run Code Online (Sandbox Code Playgroud)
如果类型被构造为临时类型,则会出现编译器错误。
以下代码定义了整个程序。这个程序标准是否符合(最新版本)?
void foo();
int main()
{
auto x = &foo;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是一个方便的快捷方式。
这段代码没有实际用途,我只是好奇。