gpt4 book ai didi

c++ - 从嵌套结构调用 protected 基类函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:29:52 24 4
gpt4 key购买 nike

通常嵌套结构可以访问所属类publicprotectedpublic 成员函数。从嵌套结构中调用基类的 protected 成员函数也没有问题,即以下代码可以正确编译和工作:

#include <iostream>

class Base
{
public:
Base()
{}

protected:
void baseProtectedFunc()
{
std::cout << __func__ << "Called for Base\n";
}
};

class Derived : public Base
{
public:
explicit Derived() : Base()
{}

void accessBaseProtectedFuncFromNested()
{
Nested myNested( this );
myNested();
}

private:
struct Nested
{
explicit Nested( Derived* ptr ) : derived_( ptr )
{}

void operator()()
{
derived_->baseProtectedFunc();
}

Derived* derived_;
};
};

int main( int, char** )
{
Derived myDerived;
myDerived.accessBaseProtectedFuncFromNested();
return 0;
}

现在,考虑以下代码,它使用 mpl::inherit_linearly 为派生生成基类,使用 mpl::vector 类型:

#include <iostream>
#include <typeinfo>

#include <boost/mpl/vector.hpp>
#include <boost/mpl/inherit.hpp>
#include <boost/mpl/inherit_linearly.hpp>
#include <boost/mpl/for_each.hpp>

template<typename T>
class Base
{
public:
Base()
{}

protected:
void baseProtectedFunc()
{
std::cout << __func__ << "Called for Base< " << typeid(T).name() << " >\n";
}
};

typedef boost::mpl::vector< long
, unsigned
, bool
, std::string
> parameter_type_list_t;

typedef boost::mpl::inherit_linearly< parameter_type_list_t
, boost::mpl::inherit< boost::mpl::_1
, Base< boost::mpl::_2 > >
>::type base_types;

class Derived : public base_types
{
public:
explicit Derived() : base_types()
{}

template<typename T>
void accessBaseProtectedFuncFromNested()
{
Nested myNested( this );

myNested.someFunc<T>();
}

private:
struct Nested
{
explicit Nested( Derived* ptr ) : derived_( ptr )
{}

template< typename T >
void someFunc()
{
Base<T>* base = static_cast<Base<T>*>( derived_ );
base->baseProtectedFunc();
}

Derived* derived_;
};
};

int main( int, char** )
{
Derived myDerived;
myDerived.accessBaseProtectedFuncFromNested<unsigned>();

return 0;
}

使用 GCC 版本 4.4.6-3(在 c++03 和 c++0x 模式下)生成以下错误:

friend-prot.cpp: In member function ‘void Derived::Nested::someFunc() [with T = unsigned int]’:
friend-prot.cpp:47: instantiated from ‘void Derived::accessBaseProtectedFuncFromNested() [with T = unsigned int]’
friend-prot.cpp:82: instantiated from here
friend-prot.cpp:17: error: ‘void Base<T>::baseProtectedFunc() [with T = unsigned int]’ is protected
friend-prot.cpp:72: error: within this context

如果我创建我尝试调用 public 的函数,代码将按预期进行编译和工作。

我可以通过向 derived 添加一个额外的 private 成员函数来解决这个问题,它只是转发来自 Nested 的调用,即:

struct Nested
{
explicit Nested( Derived* ptr ) : derived_( ptr )
{}

template< typename T >
void operator()()
{
derived_->forwarder<T>();
}

Derived* derived_;
};


template< typename T >
void forwarder()
{
Base<T>::baseProtectedFunc();
}

我不明白为什么在使用 mpl::inherit 时,如果 protected 不能调用 baseProtectedFunc()

为什么我可以在第一个示例中调用基类保护函数,而在第二个示例中却不行?

最佳答案

你会发现转发函数写成同样的错误

template <typename T>
void forwarder()
{
Base<T>* base = static_cast<Base<T>*>( derived_ );
base->baseProtectedFunc();
}

问题在于,转换为基指针使编译器无法理解 baseProtectedFunc 实际上可以使用指定指针从当前上下文访问的事实。由于这是模糊的,编译器必须假定不允许通过该指针进行访问。

由于您在转发函数中使用的语法也可以在嵌套类中使用,因此解决方案相当简单和优雅:

struct Nested
{
explicit Nested( Derived* ptr ) : derived_( ptr )
{}

template< typename T >
void someFunc()
{
derived_->Base<T>::baseProtectedFunc(); /* <-- Changed */
}

Derived* derived_;
};

关于c++ - 从嵌套结构调用 protected 基类函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13624538/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com