gpt4 book ai didi

c++ - 检测一个类型是来自主模板的特化还是用户提供的特化

转载 作者:行者123 更新时间:2023-12-04 01:06:09 30 4
gpt4 key购买 nike

假设我有这个:

template<typename T>
class my_template {...};
现在,用户有望能够专精 my_template为他们自己的类型。他们会将这些类型传递给我的一些 API 函数,这些函数将使用 my_template<T> 的属性做事。
所以在我的代码中,我有一个 my_template<T> .我想要一个需要 my_template<T> 的元函数并导致编译时值为 true如果 my_template<T>是用户提供的特化(部分或显式)和 false如果不是。
最明显的解决方案是推一个私有(private)成员别名,或其他一些 concept -可检测的私有(private)声明,进入主要 my_template定义,并依赖于用户提供的专业中不存在的定义。但是,用户可以通过提供适当的定义来伪造明确的特化。所以这不是万无一失的。
这个问题不是诡辩。 C++20 规范有一个元函数 ITER_CONCEPT(I) ,根据是否 std::iterator_traits<I> 具有不同的内部行为来自主模板或用户提供的特化。当然,作为标准库,他们可以创建一个前缀为 __ 的标识符。作为主模板的成员,从而将来自用户空间的任何试图伪造声明为未定义行为。
这是只有编译器/标准库实现才能万无一失的事情,还是可以在 C++20 中做到这一点?

最佳答案

The most obvious solution is to shove a private member alias, or some other concept-detectable private declaration, into the primary my_template definition, and rely on that not being present in user-provided specializations. However, a user could forge an explicit specialization by providing an appropriate definition. So this isn't foolproof.


基本上就是这样,是的。例如,libstdc++ 的迭代器特征的主类模板继承自隐藏的基类模板,然后检查从该基类的继承。
是的,用户可以通过提供适当的定义来打造明确的特化 - 但是,就像,不要。这不是你偶然会做的事情,这是明确而毫无意义的恶意,典型的说法是库和语言防御墨菲,而不是马基雅维利。
使用模块,您可以通过导出主模板而不是实际导出用于检查类模板是否专用的基类来使用户更难显式恶意:
export module std;

namespace std {
template <typename T> struct __iterator_traits { };

template <typename T>
export struct iterator_traits : __iterator_traits { };
}
现在用户甚至不能命名 std::__iterator_traits为了打破图书馆。也许反射仍然会给他们一种方法来做到这一点(假设这些东西仍然可以访问),但现在他们真的会跳过很多圈。

说到反射,当前指定的 API ( P1240) 的一部分包括函数 is_specialization , is_partial_specialization , 和 is_explicit_specialization .如果这些是我认为的意思,那么当我们最终得到反射(reflection)时,图书馆就不会使用这些魔法基础/魔法成员黑客,而可以直接检查提供的特化是部分特化还是显式特化,或者不是。我认为图书馆应该添加 is_primary_specialization为了完整性。

关于c++ - 检测一个类型是来自主模板的特化还是用户提供的特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66393470/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com