C++ 如何允许模板函数具有朋友(类似)访问权限?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/922545/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to allow template function to have friend(-like) access?
提问by CW Holeman II
How does one modify the following code to allow template function ask_runUI()
to use s_EOF
without making s_EOF
public?
如何修改以下代码以允许模板函数ask_runUI()
使用s_EOF
而不s_EOF
公开?
#include <string>
#include <iostream>
#include <sstream>
#include <vector>
class AskBase {
protected:
std::string m_prompt;
std::string m_answer;
virtual bool validate(std::string a_response) = 0;
public:
AskBase(std::string a_prompt):m_prompt(a_prompt){}
std::string prompt(){return m_prompt;}
std::string answer(){return m_answer;}
static int const s_EOF = -99;
static int const s_BACKUP = -1;
static int const s_OK = 1;
int ask_user();
};
template<typename T> class Ask : public AskBase{
public:
Ask(std::string a_prompt):AskBase(a_prompt){}
bool validate(std::string a_response);
};
template<> bool Ask<std::string>::validate(std::string a_response){return true;}
template<> bool Ask<int>::validate(std::string a_response){int intAnswer;
return (std::stringstream(a_response) >> intAnswer);}
int AskBase::ask_user(){
for(;;){
std::cout << "Enter " << m_prompt;
std::string response;
getline(std::cin, response);
if (std::cin.eof())
return s_EOF;
else if (response == "^")
return s_BACKUP;
else if (validate(response)){
m_answer = response;
return s_OK;
}
}
return s_EOF;
}
template<typename T> int ask_runUI(T& a_ui){
int status = AskBase::s_OK;
for (typename T::iterator ii=a_ui.begin();
status!=AskBase::s_EOF && ii!=a_ui.end();
ii+=((status==AskBase::s_BACKUP)?((ii==a_ui.begin())?0:-1):1)
status = (*ii)->ask_user();
return (status == AskBase::s_OK);
}
int main(){
std::vector<AskBase*> ui;
ui.push_back(new Ask<std::string>("your name: "));
ui.push_back(new Ask<int>("your age: "));
if (ask_runUI(ui))
for (std::vector<AskBase*>::iterator ii=ui.begin(); ii!=ui.end(); ++ii)
std::cout << (*ii)->prompt() << (*ii)->answer() << std::endl;
else
std::cout << "\nEOF\n";
}
回答by Michael Kristofik
If you want a template function to be a friend, you must say so in the class declaration. Change the line that declares the friend function to this:
如果你想让模板函数成为朋友,你必须在类声明中这么说。将声明朋友函数的行更改为:
template <typename T>
friend int ask_runUI(T& a_ui);
Now, if your class is itself a template, things get a lot more complicated. Template friends are not trivial to do correctly. For that, I'll refer you to what C++ FAQ Litesays on the subject.
现在,如果你的类本身就是一个模板,事情就会变得更加复杂。模板朋友要正确做起来并不容易。为此,我将向您介绍C++ FAQ Lite关于该主题的内容。
回答by aJ.
This worked for me!
这对我有用!
class AskBase {
public:
AskBase(){}
template<typename T>
friend int ask_runUI(T& a_ui);
private:
static int const s_EOF = -99;
static int const s_BACKUP = -1;
static int const s_NULL = 0;
static int const s_OK = 1;
};
//int ask_runUI()
template<typename T>
int ask_runUI(T& a_ui)
{
return AskBase::s_NULL;
}
回答by Nikolai Fetissov
The simplest is probably to replace static int const
members with enumeration and not mess with friend
s:
最简单的可能是static int const
用枚举替换成员,而不是用friend
s来替换成员:
class AskBase {
public:
enum { Eof = -99, Null = 0, Ok = 1, Backup = -1 };
...
};