当前位置: 首页 > 工具软件 > Zeno > 使用案例 >

ZENO代码学习

燕博文
2023-12-01

目录

1  any.h

struct poly_base_of : std::false_type {};

std::false_type

typename T::poly_base

using type = typename T::poly_base;

std::void_t() = std::declval())>>

std::declval

virtual std::shared_ptr<_AnyBase> clone() const = 0;

_AnyImpl(Ts &&...ts) : t(std::forward(ts)...) {}

 shared_any(std::nullptr_t = nullptr) : m_ptr(nullptr) {}

template ::value, int> = 0>

auto p = dynamic_cast<_AnyImpl

*>(m_ptr.get());

2  Any.h

f(std::integral_constant{})

using tuple_type = std::tuple;

std::any

std::variant

std::move

std::make_optional(v);

if constexpr (std::is_same_v, Any>)

constexpr

if (typeid(V) != a.type()) return std::nullopt;

decltype(auto) v = std::any_cast(a);

if constexpr (std::is_pointer_v)

decltype(auto) ptr = std::static_pointer_cast(std::move(v));

 if (!std::holds_alternative(v)) return std::nullopt;

using Ti = std::tuple_element_t;

3  AttrVector.h

decltype(auto)

std::visit

template 

std::forward

std::get

std::holds_alternative

 values.emplace_back(std::forward(ts)...);

4  学习修复Exception: invalid primitive attribute name: `pos`


1  any.h

struct poly_base_of : std::false_type {};

无参数的构造函数数组初始化时调用

C++ 结构体(struct)最全详解 - 简书 (jianshu.com)

std::false_type

  • true_type,false_type:代表类型(类类型)
  • true,false:代表值

(C++模板编程):std::true_type与std::false_type_baidu_41388533的博客-CSDN博客_std::false_type

typename T::poly_base

当你想告知编译器iterator是类型而不是变量,只需要用typename

C++(八)——typename用法_iotflh的博客-CSDN博客_typename用法

using type = typename T::poly_base;

using 语法是如何定义模板别名

C++11使用using定义别名(替代typedef) (biancheng.net)

std::void_t<decltype(std::declval<T &>() = std::declval<T>())>>

decltype

decltype 是“declare type”的缩写,译为“声明类型”。

auto 只能用于类的静态成员,不能用于类的非静态成员(普通成员),如果我们想推导非静态成员的类型,这个时候就必须使用 decltype 了

C++ decltype类型推导完全攻略 (biancheng.net)

std::declval

返回一个类型的右值引用,不管是否有没有默认构造函数或该类型不可以创建对象。(可以用于抽象基类);

c++11 std::declval 详解 - 程远春 - 博客园 (cnblogs.com)

  • std::declval是c++11新标准中出现的函数模板,没有函数体(只有声明,没有实现),无法被调用,
  • 一般用于与decltype,sizeof等关键字配合来进行类型推导、占用内存空间计算等

(344条消息) (C++模板编程):std::declval(上)_baidu_41388533的博客-CSDN博客_std::declval

virtual std::shared_ptr<_AnyBase> clone() const = 0;

 std::shared_ptr

make_shared,这是最安全的分配使用方式,他是使用参数的构造函数来生成对像,也就是参数必须符合构造函数的参数表。我们通常使用auto来保存他返回的结果。

(344条消息) shared_ptr的详解_啊啦啦的博客-CSDN博客_shared_ptr

_AnyImpl(Ts &&...ts) : t(std::forward<Ts>(ts)...) {}

std::forward

std::forward通常是用于完美转发的,它会将输入的参数原封不动地传递到下一个函数中,这个“原封不动”指的是,如果输入的参数是左值,那么传递给下一个函数的参数的也是左值;如果输入的参数是右值,那么传递给下一个函数的参数的也是右值。

浅谈std::forward - 知乎 (zhihu.com)

 shared_any(std::nullptr_t = nullptr) : m_ptr(nullptr) {}

std::nullptr_t

nullptr_t是一种数据类型而nullptr是该类型的一个实例。通常情况下,也可以通过nullptr_t类型创建另一个新的实例。

第6课 nullptr_t和nullptr - 浅墨浓香 - 博客园 (cnblogs.com)

template <class T, std::enable_if_t<poly_base_of<T>::value, int> = 0>

std::enable_if_t

当一份标准模板函数无法解决特定情况时,按条件匹配进入特定模板函数就变成了不可或缺.

大部分的STL、TR1 的代码都会在使用 enable_if 或者 enable_if_t 时, 为第二个类型提供一个 int, 然后设定一个 0 为默认值.

C++模板 按条件匹配(enable_if_t) - 简书 (jianshu.com)

auto p = dynamic_cast<_AnyImpl<P> *>(m_ptr.get());

dynamic_cast

dynamic_cast是四个强制类型转换操作符中最特殊的一个,它支持运行时识别指针或引用

C++强制类型转换操作符 dynamic_cast - 狂奔~ - 博客园 (cnblogs.com)

2  Any.h

f(std::integral_constant<int, First>{})

std::integral_constant

这个类是所有traits类的基类

(344条消息) c++模板元编程六:integral_constant 类_Dean Chen的专栏-CSDN博客_integral_constant

using tuple_type = std::tuple<Ts...>;

std::tuple

tuple是一个固定大小的不同类型(异质,heterogeneous)值的集合(这一点是tuple与其他常规STL容器的最大不同,即它可以同时存放不同类型的数据)。
泛化的std::pair(也即std::pair是tuple的一个特例,长度受限为2)。

std::tuple - osbreak - 博客园 (cnblogs.com)

 std::any(static_cast<any_underlying_type_t<T> const &>(t))

std::any

std: any是一种值类型,它能够更改其类型,同时仍然具有类型安全性。也就是说,对象可以保存任意类型的值,但是它们知道当前保存的值是哪种类型。在声明此类型的对象时,不需要指定可能的类型。 

(344条消息) C++17之std::any_janeqi1987的专栏-CSDN博客_std::any

static_cast

static_cast 是“静态转换”的意思,也就是在编译期间转换,转换失败的话会抛出一个编译错误。

  • 原有的自动类型转换,例如 short 转 int、int 转 double、const 转非 const、向上转型等;
  • void 指针和具体类型指针之间的转换,例如void *int *char *void *等;
  • 有转换构造函数或者类型转换函数的类与其它类型之间的转换,例如 double 转 Complex(调用转换构造函数)、Complex 转 double(调用类型转换函数)。

C++四种类型转换运算符:static_cast、dynamic_cast、const_cast和reinterpret_cast_C语言中文网 (biancheng.net)

std::variant

c++17中引入了std::variant。std::variant类似union

std::visit获取到std::variant实际存储的类型的时间复杂度为O(1),性能不会随着std::varant中类型的增多而降低。

使用std::variant - 知乎 (zhihu.com)

 

std::move

唯一的功能是将一个左值强制转化为右值引用,继而可以通过右值引用使用该值,以用于移动语义。从实现上讲,std::move基本等同于一个类型转换:static_cast<T&&>(lvalue);

  1. std::move是将对象的状态或者所有权从一个对象转移到另一个对象,只是转移,没有内存的搬迁或者内存拷贝所以可以提高利用效率,改善性能.。

(344条消息) c++ 之 std::move 原理实现与用法总结_学之知之的博客-CSDN博客_std::move

std::make_optional(v);

std::optional<>为任意类型的可空实例建模。实例可以是成员、参数或返回值。还可以认为std::optional<>是一个包含0或1个元素的容器。

(344条消息) C++17之std::optional_janeqi1987的专栏-CSDN博客_std::optional

if constexpr (std::is_same_v<std::decay_t<T>, Any>)

std::is_same_v

C++11中的std::is_same可以判断输入的类型是否是指定的模板类型。测试代码如下:

std::is_same的用法_clever101的专栏-CSDN博客

基于 C++ 11 别名模板的 std::conditional_t 和基于 C++ 14 变量模板的 std::is_same_v 都比基于 std::conditional/std::is_same 的传统方案更快。

浅谈 C++ 元编程 | BOT Man JL (bot-man-jl.github.io)

constexpr

检测constexpr函数是否产生编译时期值的方法很简单,就是利用std::array需要编译期常值才能编译通过的小技巧。这样的话,即可检测你所写的函数是否真的产生编译期常值了。

C++ const 和 constexpr 的区别? - 知乎

if (typeid(V) != a.type()) return std::nullopt;

std::nullopt

std::nullopt 是 C++ 17 中提供的没有值的 optional 的表达形式,等同于 { } 。

C++17 新特性之 std::optional(上) - 知乎 (zhihu.com)

decltype(auto) v = std::any_cast<V const &>(a);

std::any_cast

对包含的对象执行类型安全访问。

std::any_cast - C++ - API 参考文档 (apiref.com)

if constexpr (std::is_pointer_v<T>)

std::is_pointer_v

检查 T 是否为指向对象指针或指向函数指针(但不是指向成员/成员函数指针)。若 T 是对象/函数指针类型,则提供等于 true 的成员常量 value 。否则, value 等于 false 。

std::is_pointer - C++中文 - API参考文档 (apiref.com)

decltype(auto) ptr = std::static_pointer_cast<U>(std::move(v));

std::static_pointer_cast

    std::static_pointer_cast<DerivedClass>(ptr_to_base)->f(); // OK

    // (构造临时 shared_ptr ,然后调用 operator-> )

    static_cast<DerivedClass*>(ptr_to_base.get())->f(); // 亦 OK

    // (直接转型,不构造临时 shared_ptr )

std::static_pointer_cast, std::dynamic_pointer_cast, std::const_pointer_cast, std::reinterpret_pointer_cast - C++中文 - API参考文档 (apiref.com)

 if (!std::holds_alternative<T>(v)) return std::nullopt;

std::holds_alternative

检查 variant v 是否保有可选项 T 。若 T 不在 Types... 准确出现一次,则此调用为病式。

std::holds_alternative - C++中文 - API参考文档 (apiref.com)

using Ti = std::tuple_element_t<i, TupleT>;

std::tuple_element_t

提供 tuple 元素类型的编译时带下标访问。

std::tuple_element<std::tuple> - C++中文 - API参考文档 (apiref.com)

3  AttrVector.h

decltype(auto)

在推导变量类型时,先用初始化表达式替换decltype(auto)当中的auto,然后再根据decltype的语法规则来确定变量的类型。

C++14尝鲜:decltype 和 decltype(auto)_zwvista的专栏-CSDN博客_decltype

std::visit

https://blog.csdn.net/janeqi1987/article/details/100568146

template <class ...Ts>

c++11 新增加了变长模板的支持.

介绍C++11标准的变长参数模板 - zenny_chen - 博客园 (cnblogs.com)

std::forward

std::forward通常是用于完美转发的,它会将输入的参数原封不动地传递到下一个函数中

浅谈std::forward - 知乎 (zhihu.com)

std::get

std::get 是一个模板函数,它需要在编译期间知道模板参数

为什么std :: get不能用于变量? - 问答 - 云+社区 - 腾讯云 (tencent.com)

std::array中的std::get<n>() - Kjing - 博客园 (cnblogs.com)

std::holds_alternative

若 variant 当前保有可选项 T 则为 true ,否则为 false 。

std::holds_alternative - C++中文 - API参考文档 (apiref.com)

 values.emplace_back(std::forward<Ts>(ts)...);

emplace_back

emplace_back能就地通过参数构造对象,不需要拷贝或者移动内存。

当结构体中没有提供相应的构造函数时就不能用emplace了,这时就只能用push_back。

emplace_back减少内存拷贝和移动 - 小金乌会发光-Z&M - 博客园 (cnblogs.com)

4  学习修复Exception: invalid primitive attribute name: `pos`

把std::visit改到attr_visit,从而能够访问到'pos'。



/zeno/zeno/nodes/prim/PrimitiveOp.cpp中添加的代码:

zeno/zeno/zeno/nodes/prim/PrimitiveOp.cpp at master · zenustech/zeno (github.com)

primOut->attr_visit(attrOut, [&] (auto &arrOut) { primA->attr_visit(attrA, [&] (auto &arrA) {

}); });

primOut->attr_visit(attrOut, [&] (auto &arrOut) { primA->attr_visit(attrA, [&] (auto &arrA) { primB->attr_visit(attrB, [&] (auto &arrB) {

}); }); });

primOut->attr_visit(attrOut, [&] (auto &arrOut) { primA->attr_visit(attrA, [&] (auto &arrA) { primB->attr_visit(attrB, [&] (auto &arrB) {

}); }); });

primOut->attr_visit(attrOut, [&] (auto &arrOut) { primA->attr_visit(attrA, [&] (auto &arrA) { std::visit([&] (auto &valB) {

}, valB); }); });
 类似资料: