我有一个似乎与模板模板参数有关的问题。以下代码(GodBolt.org 上的生命代码)可以使用 GCC 编译至 11.2,但无法使用 Clang++ 编译至 13.0.1。
问题似乎出在代码的最后两行。
HullWrapper我试图实现的是记住作为别名模板传递的模板模板参数HullWrapper以便以后可以重新使用它。
特别是在倒数第二行中,我想重新构建该类派生的基本模板HullClass。我通过专门化来尝试这个HullWrapper通过别名模板记住的模板参数来专门化模板来尝试此操作。
不幸的是,这在 Clang++ 中不起作用。然而,在 G++ 中却是这样。看来,对于 Clang++ a 来说,与传递给它的模板参数的别名模板HullWrapper<Hull>不同。HullWrapper<HullClass::HullType>HullTypeTHull
#include <type_traits>
template <typename T> struct Hull {};
template <template <typename> class T>
struct HullWrapper
{
template <typename U> using HullType = T<U>;
};
struct HullClass : HullWrapper<Hull> {};
HullClass hullObj;
HullWrapper<Hull>* hullWrapperPtr2 = &hullObj;
HullClass* hullPtr = &hullObj;
// Following two lines does not compile …Run Code Online (Sandbox Code Playgroud) 我想在Perl 6中定义两种数据类型,这些数据类型源自Int但不同时Int或彼此不兼容.
例如:
Distance派生自Int0到32000的范围,和Offset派生自Int-32000到32000的范围现在我想要这些类型Distance,Offset并且Int默认情况下可以区分并且彼此不兼容.
所以(伪Perl 6):
my Distance $d = Distance(12); // ok
my Offset $o = Offset(-1); // ok
my Distance $d2 = $o; // BUMMER!
sub myprint(Int $i) { say $i }
say $d + $o; // BUMMER!
myprint $d; // BUMMER!
myprint Int($d); // ok
Run Code Online (Sandbox Code Playgroud)
等等!如果我试图隐含地混合Distances和Offsets,我希望Perl 6编译器抱怨.
在我迄今读过的书中,没有提示如何实现这一点.问谷歌几天也没有给我任何答案是否可能,如果是,如何?
我发现subset但是这只对一个类型设置了一些限制,但是没有使它与原始类型不兼容.此外,如果在原始类型及其子集中都满足其限制,则它与原始类型无法区分.
所以我想在这里询问是否有人知道Perl 6中是否可以这样做?如果是的话,我该怎么办呢?
在C++ 14 Sec 15.4; 2中声明,......异常规范不应出现在typedef声明或别名声明中.
这意味着禁止以下内容:
typedef void (*fn)(int) noexcept;
Run Code Online (Sandbox Code Playgroud)
但是,措辞不会出现意味着令牌noexcept不能出现在typedef声明中的任何地方吗?
比如这些都是禁止的吗?
typedef void (*fn1)(void (*)(int) noexcept);
typedef decltype(std::declval<void (*)(int)noexcept>()) fn2;
Run Code Online (Sandbox Code Playgroud)
这两个都试图定义一个类型fn1,fn2并且能够指向一个函数,该函数接受一个函数的指针,该函数接受int并且不返回任何内容,同时承诺永远不会抛出异常.
因此在我的示例中,异常规范不适用于顶层类型fn1resp.fn2由typedef这些函数可能接收的参数引入.
那么我应该逐字取15.4; 2,因此我的两个例子都无效?或者只是应用于禁止的类型定义,我的例子是正确的?