[英]Understanding templates defined inside templates (C++)
根據我的理解,以下兩個程序應該實際上是相同的,但是第二個程序編譯失敗。 請注意,在這個簡化的示例中,嵌套顯然是無用的,但在原始上下文中它是必要的。
版本 1:按預期工作
#include <iostream>
template<typename Value>
struct Anything {
Value value;
};
using A = const char *;
template<template<typename> class B>
struct Inner {
template<typename C>
using type = B<C>;
};
template<template<typename> class B>
struct OuterBase {
B<A> b;
void
print() { std::cout << "b: " << b.value << std::endl; }
};
using Outer = OuterBase<Inner<Anything>::type>; // this version works
int
main()
{
Outer outer;
outer.b.value = "foo";
outer.print();
return 0;
}
此版本中的編譯器錯誤是“期望一個模板,得到TypeBox<A>::Inner<Anything>::type
”。
版本 2:因編譯錯誤而失敗
#include <iostream>
template<typename Value>
struct Anything {
Value value;
};
template<typename A>
struct TypeBox {
template<template<typename> class B>
struct Inner {
template<typename C>
using type = B<C>;
};
template<template<typename> class B>
struct OuterBase {
B<A> b;
void
print() { std::cout << "b: " << b.value << std::endl; }
};
using Outer = OuterBase<Inner<Anything>::type>; // compile error here
};
int
main()
{
using Box = typename TypeBox<const char *>::Outer;
Box box;
box.b.value = "foo";
box.print();
return 0;
}
我希望TypeBox
結構在解析內部類型時是透明的,但根據gcc 12.2.1
,它不是。 為什么不?
第二個示例的不同之處在於,編譯器無法在模板的定義點驗證Inner<Anything>::type
確實是 class 模板或別名模板。 問題是Inner
是一個嵌套的 class 模板,理論上你可以稍后為給定的模板參數部分或顯式地特化Inner
,以便type
命名,例如類型。
因此編譯器傾向於要求您將template
關鍵字放在模板名稱之前,在這種情況下 state 它確實是一個模板:
using Outer = OuterBase<Inner<Anything>::template type>;
我的理解是,盡管從技術上講,標准中沒有任何內容需要使用template
,但這並不完全清楚。 但是,該標准確實允許在此 position 中使用template
關鍵字,但將在 C++23 中棄用此允許。 如果我沒記錯的話,即使對於以前的標准修訂版(作為缺陷報告),編譯器將來也應該允許在沒有template
關鍵字的情況下這樣做。 執行此測試沒有任何意義。
另請參閱CWG 問題 1478和提議棄用P1787R6的論文。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.