C++ 具有CRTP+的友元函数;如果不工作,是否启用_?
以下代码未编译,我不知道原因:C++ 具有CRTP+的友元函数;如果不工作,是否启用_?,c++,templates,c++11,variadic-templates,crtp,C++,Templates,C++11,Variadic Templates,Crtp,以下代码未编译,我不知道原因: #include <type_traits> // Base class definition template<template<typename> class CRTP, typename T> class Base { // Friend function declaration public: template<template<typename> class CRTP
#include <type_traits>
// Base class definition
template<template<typename> class CRTP, typename T> class Base
{
// Friend function declaration
public:
template<template<typename> class CRTP0, typename T0, class>
friend int func(const Base<CRTP0, T0>& rhs);
// Protected test variable
protected:
int n;
};
// Friend function definition
template<template<typename> class CRTP0, typename T0,
class = typename std::enable_if<true>::type>
int func(const Base<CRTP0, T0>& rhs)
{
return rhs.n;
}
// Derived class definition
template<typename T> class Derived : public Base<Derived, T> {};
// Main
int main()
{
Derived<int> x;
func(x);
return 0;
}
#包括
//基类定义
模板类基
{
//友元函数声明
公众:
模板
friend int func(常数基和rhs);
//受保护测试变量
受保护的:
int n;
};
//友元函数定义
模板
int func(常数基和rhs)
{
返回rhs.n;
}
//派生类定义
派生的模板类:公共基{};
//主要
int main()
{
导出x;
func(x);
返回0;
}
GCC 4.6.2(以及LWS上的GCC 4.7.1)告诉我:
error: 'int Base<Derived, int>::n' is protected
错误:“int Base::n”受保护
也就是说,基本上,友谊没有被正确地检测到。因为这只是我代码的一个摘录,所以我想把friend函数的定义放在类定义之外,就像这里一样。那么,问题是什么?如何解决
编辑:我修改了代码,试图隔离问题并使其更具可读性。当前的enable_if始终为true,但对于我的实际代码,我将有一个“real”条件,这里它只是隔离问题
EDIT2:liveworkspace在这里:如果您尝试显式调用
func
:
func<Derived, int, void>(x);
func(x);
g++抱怨:
source.cpp:31:31: error: call of overloaded 'func(Derived<int>&)' is ambiguous
source.cpp:31:31: note: candidates are:
source.cpp:19:5: note: int func(const Base<CRTP0, T0>&) [with CRTP0 = Derived; T0 = int; <template-parameter-1-3> = void]
source.cpp:9:20: note: int func(const Base<CRTP0, T0>&) [with CRTP0 = Derived; T0 = int; <template-parameter-2-3> = void; CRTP = Derived; T = int]
source.cpp:31:31:错误:重载“func(派生&)”的调用不明确
资料来源:cpp:31:31:注:候选人为:
source.cpp:19:5:注意:int func(const Base&)[带CRTP0=Derived;T0=int;=void]
source.cpp:9:20:注意:int func(const Base&)[带CRTP0=Derived;T0=int;=void;CRTP=Derived;T=int]
我认为问题在于
friend
声明没有与函数定义正确标识;相反,正在声明另一个函数模板。即使预先声明了类和函数模板,也会发生这种情况。我在gcc方面也有类似的问题。我认为这是一个编译器错误:因为您的函数模板有三个模板参数,而不是友元声明中的两个,所以它与它们不匹配。为了使您的意图能够正确地使用gcc,您必须精确地匹配友元声明。在函数返回类型上使用SFINAE最容易实现这一点
// Friend function definition
template<template<typename> class CRTP0, typename T0>
typename std::enable_if<true,int>::type
func(const Base<CRTP0, T0>& rhs)
{
return rhs.n;
}
//友元函数定义
模板
typename std::enable_if::type
func(常数基和rhs)
{
返回rhs.n;
}
我希望这段代码只是为了好玩而写的,即使有人纠正它,也不会在任何地方使用:)当然,这只是一段测试代码,但我有一段基于这种不可读语法的真实代码…;-)在我看来,这好像是个bug,你能用clang测试一下吗?是的,clang++编译时没有任何错误。这里报告了这个bug: