Dam*_*mon 1 c++ templates c++17
在包含另一个模板类的模板类(什么重要的...可更换存储表示什么),我认为这不是在serveral的模板参数传递下来,那将是更优雅中的一个实例来传递内模板和参数达到了再次来代替.
为什么不!当然这很有效,而且更优雅!
现在,也许上面的内容有点难以理解,所以让我们看看我一直在努力做的一些(几乎可编译的)代码:
template<typename T, int n> struct foo
{
// using alias_of_T = T;
};
template<typename FOO> struct bar
{
FOO _foo;
// this works just fine!?
static constexpr int size = FOO::n;
// this indeed works, but... bleh
// using type_t = typename FOO::alias_of_T;
// this does not work?
using type_t = typename FOO::T;
type_t whatever() { return ...; }
};
//...
int main()
{
bar<foo<int, 3>> zoo;
...
Run Code Online (Sandbox Code Playgroud)
令人惊讶的是,FOO模板参数T无法访问.但更令人惊讶的是,完全可以访问n.
这背后的理由是什么?
有比使用更优雅的方式FOO::alias_of_T吗?
事实证明,我太愚蠢了,无法阅读我自己的代码!有(对@Barry的称赞)确实是一个"不同大小",即constexpr size = n原始(不是修剪,非foo-bar)代码中的别名,我似乎完全忽略了这些代码.这就解释了为什么它对非类型参数"工作正常",这并不奇怪.嗯,这很尴尬,你真的能够正确阅读你自己键入的代码......
令人惊讶的是,
FOO模板参数T无法访问.但更令人惊讶的是,完全可以访问n.
我想这取决于你对完美的定义.它实际上不可能访问n,但你发现这一点的点有点不同.确实,如果你试图使用 size:
#include <iostream>
template <typename T, int n>
struct foo { };
template <typename FOO>
struct bar {
static constexpr int size = FOO::n;
};
int main() {
bar<foo<int, 3>> zoo;
std::cout << zoo.size << '\n'; // error: n is not a member of foo<int, 3>
}
Run Code Online (Sandbox Code Playgroud)
这是因为[temp.inst]/3:
[...]特别是,除非静态数据成员本身以需要静态数据成员的定义存在的方式使用,否则不会发生静态数据成员的初始化(以及任何相关的副作用).
在你的例子中,没有任何东西需要静态数据成员存在,所以它的初始化还没有发生 - 而且这是初始化本来就是错误的.
如果您直接尝试访问名称"n",您会看到同样的事情:
template <typename T, int n>
struct foo { };
template <typename FOO>
struct bar {
int array[FOO::n]; // error
};
int main() {
bar<foo<int, 3>> zoo;
}
Run Code Online (Sandbox Code Playgroud)