简体   繁体   English

clang 3.3中的模板默认Arg替换失败

[英]Template Default Arg Substitution failure in clang 3.3

This is regarding a test case which involves default argument deduction/substitution. 这是关于涉及默认参数推导/替换的测试用例。 The test case can be summarized as : 测试用例可以总结为:

template <class T, class = typename T::I>h(T){}

template <class T, class = typename T::I>j(T){}

class A
{
   typedef int I;
   friend void h<A>(A);

};

int main()
{
   A a;
   h(a);
   j(a);
}

gcc-4.8.1 throws error for function j, since it has been not been declared friend nor it is private to class A and hence violates access rule for private member I(which is valid). gcc-4.8.1对函数j引发错误,因为尚未将其声明为好友,也不是类A的私有对象,因此违反了私有成员I(有效)的访问规则。 gcc does not throw error for function h since it has been declared as friend to class A and hence can access private member I. gcc不会为函数h引发错误,因为它已被声明为类A的朋友,因此可以访问私有成员I。

Clang throws error for both the functions. Clang会为两个函数引发错误。 Error for function j (not declared friend is valid and as expected), but it throws error even for friend function h (error : deduction of default arg failed since I is a private member of class A). 函数j的错误(未声明的朋友是有效的,并且符合预期),但是即使对于朋友功能h,它也会引发错误(错误:由于我是A类的私有成员,因此无法推导出默认arg)。 This violates the accessibility of the friend function. 这违反了朋友功能的可访问性。

I checked the code path. 我检查了代码路径。 While clang is able to deduce the default argument, it checks for access rules before doing any substitution, and gives error. 尽管clang能够推断出默认参数,但它会在进行任何替换之前检查访问规则,并给出错误信息。 Can someone please provide guidance as to how should this be fixed? 有人可以提供有关如何解决此问题的指南吗?

You forgot the return type for the template functions. 您忘记了模板函数的返回类型。

This should solve the problem : 这应该可以解决问题:

template <class T, class = typename T::I> void h(T){}

template <class T, class = typename T::I> void j(T){}

After fixing above errors, I still got errors, because 修正上述错误后,我仍然遇到错误,因为

  • you declared the typedef in the private section. 您在专用部分声明了typedef。 You need to make it public 您需要将其公开
  • you declared function friend wrongly. 您错误地声明了功能朋友。 It has two template arguments (A::I will not work, since A is not complete type) 它有两个模板参数(A ::我将无法使用,因为A不是完整类型)

Fully compilable problem is here : 完全可编译的问题在这里:

#include <iostream>

// Type your code here, or load an example.
template <class T, class = typename T::I> void h(T t){std::cout<<t.a<<std::endl;}

template <class T, class = typename T::I> void j(T t){std::cout<<t.a<<std::endl;}

class A
{
   friend void h<A,int>(A);
   friend void j<A,int>(A);
public :
   typedef int I;
  private :
  int a;

};

int main()
{
   A a;
   h(a);
   j(a);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM