我遇到了G ++ 6.1.0(-std=c++14交换机)的以下问题,我不明白为什么编译器会拒绝代码.
我有一个帮助器结构is_well_formed,它检查提供的模板模板参数是否在将另一个提供的类型替换为它时形成良好:
template<template<typename> typename R, typename T, typename = void>
struct is_well_formed : std::false_type {};
template<template<typename> typename R, typename T>
struct is_well_formed<R, T, void_t<R<T>>> : std::true_type {};
Run Code Online (Sandbox Code Playgroud)
我想检查一个类型是否可引用.所以我的想法是写下面的内容:
// (#1)
template<class T>
using reference_t = T&;
static_assert(!is_well_formed<reference_t, void>::value, "Reference to void!?");
Run Code Online (Sandbox Code Playgroud)
但是我收到编译错误:
main.cpp: In instantiation of 'struct is_well_formed<reference_t, double>':
main.cpp:62:51: required from here
main.cpp:54:20: error: type/value mismatch at argument 1 in template parameter list for 'template<template<class> class R, class T, class> struct is_well_formed'
: …Run Code Online (Sandbox Code Playgroud) 我正在开发一个使用自定义子类QOpenGLWidget来显示一些渲染的项目.在paintGL()方法结束时,它调用窗口小部件的update()方法来触发重绘事件(如果它可见).现在我想为QVTKWidget我的Ui 添加一个额外的东西,我通过使用这样的东西:
QVBoxLayout* layout = findChild<QVBoxLayout*>("layout_simulation");
QVTKWidget* widget = new QVTKWidget();
// Setup arrow
vtkSmartPointer<vtkArrowSource> arrowSource = vtkSmartPointer<vtkArrowSource>::New();
[more VTK stuff...]
widget->GetRenderWindow()->AddRenderer(renderer);
renderer->AddActor(arrowActor);
renderer->ResetCamera();
// Add widget to ui
layout->addWidget(widget);
Run Code Online (Sandbox Code Playgroud)
VTK小部件已添加到ui并按预期工作.问题是,只要我使用该layout->addWidget()方法,我的所有其他QOpenGLWidget对象都会变黑并且不显示任何内容.另外这款黑色不是的背景色VTKRenderer,因为其他部件仍然是黑色的,即使我改变VTK构件的背景颜色.我检查了一下,然后paintGL()在循环中调用了静止但它只是没有显示任何内容.我很确定我没有在我的widget子类中使用任何不好的OpenGL代码,所以我猜它与QOpenGLWidgetand 的内部初始化有关QVTKWidget.如果省略所有VTK调用并添加新创建的,则会发生同样的情况QVTKWidget.
有趣的是,如果我省略了layout->addWidget()调用,VTK会在一个单独的窗口中打开渲染器,所有OpenGL小部件都可以正常工作.但我当然希望将渲染器嵌入到我的UI中.
有没有人有这方面的经验,或者你知道我可能遇到的任何陷阱,或者是否有任何可能导致此问题的常见问题?
BTW:我使用OpenGL 3.3核心配置文件和我的QOpenGLWidget子类的自定义着色器.
编辑:我删除了我对3.3核心配置文件的请求,现在它使用4.4兼容性配置文件.我猜它现在使用相同的配置文件,VTKRenderer所以这可以排除作为错误的来源.
根据我的经验,在const和非const版本的成员方法中使用相同的代码是一种常见的现象.避免复杂方法的代码重复的一种方法是使用a const_cast去除非const版本中的常量,如在Effective C++(第3项)中推荐的Scott Meyers.然而,这对于可能只返回指针的非常短的方法是没有益处的 - 当然,在这种情况下复制不是那么有问题.这仍然让我想知道是否存在没有关键字或等效替换铸件的原因.我可以想象使用以下声明:
autoconst Data* const getData() autoconst;
Run Code Online (Sandbox Code Playgroud)
当然这个关键字不会添加任何以前无法实现的功能,但我认为它会很好.据我所知,auto关键字同样不允许任何新的结构,但在代码中是一个很好的简化 - 不可否认的是更广泛(如果我错了请纠正我).
我的问题是这是否与C++标准中的某些规则相冲突 - 如果不是,它是否只是没有用到实现.
在C++标准的最新工作草案(第572页)中,转换构造函数的std::variant注释为:
template <class T> constexpr variant(T&& t) noexcept(see below );
Run Code Online (Sandbox Code Playgroud)
令Tj为如下确定的类型:为每个替代类型Ti构建虚函数FUN(Ti).由表达式的重载决策选择的重载FUN(Tj)
FUN (std::forward<T>(t))定义了替代Tj,它是构造后包含的值的类型.效果:初始化*this以保存替代类型Tj并直接初始化包含的值,就像直接非列表初始化它一样
std::forward<T>(t).[...]
备注:该函数不应参与重载决策,除非
is_same_v<decay_t<T>, variant>为假,除非is_constructible_v<Tj, T>为真,除非表达式FUN ( std::forward<T>(t))(FUN是上述虚函数集)形成良好.
在cppreference上,以下示例用于说明转换:
variant<string> v("abc"); // OK
variant<string, string> w("abc"); // ill-formed, can't select the alternative to convert to
variant<string, bool> x("abc"); // OK, but chooses bool
Run Code Online (Sandbox Code Playgroud)
你如何模仿假想的重载决策来获得最终类型Tj?
在下面的代码中,不可能从对实现相同特征的动态大小类型的引用中获得对特征对象的引用。为什么会这样呢?究竟是什么区别&dyn Trait和&(?Sized + Trait)我是否可以使用这两种调用方法特质?
实现的类型FooTraitContainerTrait可能例如具有type Contained = dyn FooTrait或type Contained = T在哪里T实现的具体类型FooTrait。在这两种情况下,都很难获得&dyn FooTrait。我想不出另一种情况,这是行不通的。为什么在通用情况下这不可能FooTraitContainerTrait?
trait FooTrait {
fn foo(&self) -> f64;
}
///
trait FooTraitContainerTrait {
type Contained: ?Sized + FooTrait;
fn get_ref(&self) -> &Self::Contained;
}
///
fn foo_dyn(dyn_some_foo: &dyn FooTrait) -> f64 {
dyn_some_foo.foo()
}
fn foo_generic<T: ?Sized + FooTrait>(some_foo: &T) -> f64 {
some_foo.foo()
}
///
fn foo_on_container<C: FooTraitContainerTrait>(containing_a_foo: &C) -> …Run Code Online (Sandbox Code Playgroud) 我想存储未知数量的字符串,然后按照添加的顺序读取它们.正如我所说,我需要的唯一功能是:
问题是我想从trie的一部分输出字符串.因此,在返回字符串之前计算字符串会使操作所需的时间加倍.
(另一个解决方案是使用属性跟踪trie中的字符串数量,但因为我只想返回trie的一部分,这也不是一个完美的解决方案)
我正在尝试使用 ffmpeg 对 UHD HDR 视频流进行色调映射(和调整大小)。以下命令:
ffmpeg -vsync 0 -hwaccel cuda -init_hw_device opencl=ocl -filter_hw_device ocl
-threads 1 -extra_hw_frames 3 -c:v hevc_cuvid -resize 1920x1080 -i "INPUT.hevc"
-vf "hwupload,
tonemap_opencl=tonemap=mobius:param=0.01:desat=0:r=tv:p=bt709:t=bt709:m=bt709:format=nv12,
hwdownload,format=nv12,hwupload_cuda"
-c:v hevc_nvenc -b:v 8M "OUTPUT.hevc"
Run Code Online (Sandbox Code Playgroud)
似乎有效(RTX 3080 上大约 200 FPS)。然而,我注意到它仍然使用一个 CPU 核心,并且 GPU 使用率据报告仅为 60-70%。当我只在没有任何滤镜的情况下调整大小时,我会在 100% GPU 使用率下获得大约 400FPS 的速度。
我怀疑最后的hwdownload,format=nv12,hwupload_cuda语句有问题,因为这增加了通过主内存的绕道。我尝试只使用hwupload_cuda而不使用hwdownload(就像这里建议的那样: https: //stackoverflow.com/a/55747785/929037在本答案末尾附近的过滤器示例中),但后来出现以下错误:
Impossible to convert between the formats supported by the filter 'Parsed_tonemap_opencl_1' and the filter 'auto_scaler_0'
Error reinitializing filters!
Failed to inject …Run Code Online (Sandbox Code Playgroud)