C++:将模板参数的模板类型成员加为好友的语法正确吗
C++: Correct syntax for friending a template type member of template parameter?
我有一个类,它接受模板类型参数(tTRAIT)。我想成为tTRAIT的模板类型成员别名的好友,但我搞不清语法。(这可能吗?)。
template <bool bBOOL>
struct SFoo {};
struct STrait
{
template <bool bBOOL>
using TFoo = SFoo<bBOOL>;
};
template <typename tTRAIT>
struct SBar
{
template <bool bBOOL>
friend typename tTRAIT::template TFoo<bBOOL>;
};
SBar<STrait> bar;
Clang的错误(在friend
线上)是:
error: friend type templates must use an elaborated type
我试过用尽我能想到的所有可能的组合:
friend tTRAIT::TFoo;
friend tTRAIT::template TFoo;
friend typename tTRAIT::TFoo;
friend typename tTRAIT::template TFoo;
template <bool bBOOL> friend tTRAIT::TFoo;
template <bool bBOOL> friend tTRAIT::TFoo<bBOOL>;
template <bool bBOOL> friend tTRAIT::template TFoo;
template <bool bBOOL> friend tTRAIT::template TFoo<bBOOL>;
template <bool bBOOL> friend typename tTRAIT::TFoo;
template <bool bBOOL> friend typename tTRAIT::TFoo<bBOOL>;
template <bool bBOOL> friend typename tTRAIT::template TFoo;
template <bool bBOOL> friend typename tTRAIT::template TFoo<bBOOL>;
我也尝试过使用using
,但似乎没有帮助。
作为一个丑陋的破解(只适用于bool参数),我可以通过手动为每个专业化添加好友来让它发挥作用。
friend typename tTRAIT::template TFoo<false>;
friend typename tTRAIT::template TFoo<true >;
但这太恶心了。
有人知道如何做到这一点吗,或者这是否可以做到?
我认为这是不可能的。来自标准草案N4296:
§14.5.4/1[临时朋友]
类或类模板的朋友可以是函数模板或类模板函数模板或类模板,或非模板函数或类。
这不包括别名模板,因此标准不支持您想要做的事情。这可能是由于以下摘录(强调我的):
§14.5.7/1[临时别名]
一个模板声明,其中声明是一个别名声明(第7条)将标识符声明为是一个别名模板别名模板是一个类型族的名称。
别名模板命名一个单独的类型族,因此即使有一些语法对此有意义,您也会将别名模板而不是正在别名化的模板作为好友。
例如,GCC会编译这个(Clang不会),但你实际上无法以任何合理的方式使用友谊:
template <bool B>
using MyTFoo = typename tTRAIT::template TFoo<B>;
template <bool> friend class MyTFoo;
别名模板与别名模板不同的另一个示例:
template <template <typename...> class A, template <typename...> class B>
struct is_same_template : std::false_type{};
template <template <typename...> class A>
struct is_same_template<A,A> : std::true_type{};
template <typename T> using myvec = std::vector<T>;
//this fails
static_assert(is_same_template<myvec,std::vector>::value, "wat");
使用显式实例化的手动好友关系将起作用,因为别名模板将塌陷为与别名模板完全相同的类型。类似的例子:
//this passes!
static_assert(std::is_same<myvec<int>,std::vector<int>>::value, "wat");
我可以在std=c++11模式下使用Clang 3.4.1。
此编译没有错误:
模板
struct SBar
{
private:
int j;
public:
template <bool bBOOL>
friend struct tTRAIT::TFoo;
void setJ(int j) {
this->j = j;
}
};
但是。。。我收到以下警告:警告:不支持友元模板声明的依赖嵌套名称说明符"tTRAIT::";忽略此好友声明[-Wunsupported friend]:好友结构tTRAIT::TFoo
并且我可以确认SFoo
类不是朋友(private j
的原因…)
我唯一可以编译和运行它的方法是:
struct SBar
{
private:
int j;
public:
template <bool bBOOL>
friend struct sFoo;
void setJ(int j) {
this->j = j;
}
};
很好,SFoo
类是的朋友,但它在一定程度上违反了OP要求([模板参数]的模板类型成员)。。。
我目前无法访问最近的gcc,但我认为我们正处于编译器如何解释该标准的边缘。我阅读了TartanLlama引用的章节,但无法确定这是否是有意的。也许我的第一次尝试会被gcc接受。。。
- 1d 智能指针不适用于语法 (*)++
- 助记符和指向成员语法的指针
- 有人能分解一下这个c++模板的语法吗
- C++避免重复声明的语法是什么
- QMetaObject invokeMethod的基于函数指针的语法
- 这个语法std::class<>{}(arg1, arg2) 在C++中是什么意思?
- 有没有可能有一个只有ADL才能找到的非好友功能
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 单独定义模板化嵌套类方法的正确语法
- 为什么我的好友类无法访问私人会员?
- 共享指针和具有自定义删除程序的唯一指针之间的语法差异背后的任何原因
- 错误 C2760:语法错误:映射迭代器上意外的标记"标识符",预期的";"
- 为什么派生类的好友不能使用受保护的成员?
- 为什么我会收到错误 C2143 语法错误:缺少"*"之前的';'?
- 奇怪的代码抛出编译错误模板< J,int aSize=10> C2143:语法错误:在"<"之前缺少";"
- 使用基类指针调用基类的值构造函数的语法是什么?
- 很好的语法来获取对向量/数组数据的大小引用?
- 模板好友语法
- C++:将模板参数的模板类型成员加为好友的语法正确吗
- 使"class template"成为类好友的正确语法