Хитрость заключается в том, чтобы добавить переменные окружения в файл sudoers
с помощью команды sudo visudo
и добавить следующие строки:
Defaults env_keep += "ftp_proxy http_proxy https_proxy no_proxy"
взято из ArchLinux wiki .
Для Ubuntu 14 вам нужно указывать в отдельных строках, так как он возвращает ошибки для строк с несколькими переменными:
Defaults env_keep += "http_proxy"
Defaults env_keep += "https_proxy"
Defaults env_keep += "HTTP_PROXY"
Defaults env_keep += "HTTPS_PROXY"
Основная проблема заключается в том, что вы вызываете в итераторе метод с именем first ()
. Что вы должны сделать, так это использовать свойство с именем first
:
...append(iter->first) rather than ...append(iter->first())
С точки зрения стиля вы не должны использовать new
для создания этой строки.
std::string something::toString()
{
std::map<std::string, std::string>::iterator iter;
std::string strToReturn; //This is no longer on the heap
for (iter = table.begin(); iter != table.end(); ++iter) {
strToReturn.append(iter->first); //Not a method call
strToReturn.append("=");
strToReturn.append(iter->second);
//....
// Make sure you don't modify table here or the iterators will not work as you expect
}
//...
return strToReturn;
}
edit : facildelembrar указал (в комментариях), что в современном C ++ теперь можно переписать цикл
for (auto& item: table) {
...
}
Note that the result of dereferencing an std::map::iterator is an std::pair. The values of first
and second
are not functions, they are variables.
Change:
iter->first()
to
iter->first
Ditto with iter->second
.
Не пишите метод toString ()
. Это не Java. Реализуйте оператор потока для своего класса.
Предпочитайте использовать стандартные алгоритмы вместо написания собственного цикла. В этой ситуации std :: for_each ()
предоставляет удобный интерфейс для того, что вы хотите сделать.
Если вы должны использовать цикл, но не собираетесь изменять данные, предпочтите ] const_iterator
вместо итератора
. Таким образом, если вы случайно попытаетесь изменить значения, компилятор предупредит вас.
Затем:
std::ostream& operator<<(std::ostream& str,something const& data)
{
data.print(str)
return str;
}
void something::print(std::ostream& str) const
{
std::for_each(table.begin(),table.end(),PrintData(str));
}
Затем, когда вы захотите его распечатать, просто выполните потоковую передачу объекта:
int main()
{
something bob;
std::cout << bob;
}
Если вам действительно нужно строковое представление объект, вы можете затем использовать lexical_cast
.
int main()
{
something bob;
std::string rope = boost::lexical_cast<std::string>(bob);
}
Детали, которые необходимо заполнить.
class somthing
{
typedef std::map<std::string,std::string> DataMap;
struct PrintData
{
PrintData(std::ostream& str): m_str(str) {}
void operator()(DataMap::value_type const& data) const
{
m_str << data.first << "=" << data.second << "\n";
}
private: std::ostream& m_str;
};
DataMap table;
public:
void something::print(std::ostream& str);
};
Измените ваши вызовы добавления, чтобы сказать
...append(iter->first)
и
... append(iter->second)
Кроме того, строка
std::string* strToReturn = new std::string("");
выделяет строку в куче. Если вы намереваетесь фактически вернуть указатель на эту динамически выделяемую строку, возвращаемый результат следует изменить на std :: string *.
В качестве альтернативы, если вы не хотите беспокоиться об управлении этим объектом в куче, измените локальный объявление на
std::string strToReturn("");
и измените вызовы 'append' для использования ссылочного синтаксиса ...
strToReturn.append(...)
вместо
strToReturn->append(...)
Имейте в виду, что это создаст строку в стеке, а затем скопирует ее в возвращаемая переменная. Это влияет на производительность.
iter-> first
и iter-> second
- это переменные, вы пытаетесь вызвать их как методы.