Dedukcja typu w metodzie szablonowej

0
 
#pragma once

#include <string>
#include <iostream>
#include <fstream>
#include <map>
#include <algorithm>

#include <boost/lexical_cast.hpp>

class Config {
   typedef std::map<std::string, std::string> commandsMap;
   typedef std::map<std::string, commandsMap> sectionsMap;

   public:
      Config() = delete;
      Config(std::string&& mainConf) : m_mainConf(std::move(mainConf)) {}
      //Config(std::string& mainConf) : m_mainConf(mainConf) {}
      ~Config(){}

      void parse() throw();

      void dump();

      template <typename T> const T get(const T& defValue, const std::string& section, const std::string& command) {
         try {
            std::string& t = m_sections.at(section).at(command);
            return boost::lexical_cast<T>(t);
         } catch(std::out_of_range& e) {
            return defValue;
         }
         catch(boost::bad_lexical_cast& e) {
            std::cout << e.what();
            return defValue;
         }
      }

   private:
      std::string m_mainConf;
      sectionsMap m_sections;
};


int main(int argc, char** argv) {
   if(argc != 2) {
	   std::cout << "server -c [configName]\n";
	   return 1;
   }
	try {
	  Config conf(argv[1]);
	  conf.parse();
	  conf.dump();

      Listener l(conf.get<int>(1, "NETWORK", "PORT"), conf.get<int>(1, "DEFAULT", "THREADS"));
      l.init();
      l.run();
   } catch(std::runtime_error& e) {
	   std::cout<< e.what();
   } catch(std::logic_error& e) {
	   std::cout<< e.what();
   }
   catch(...) {
	   std::cout << "NIEZNANY WYJATEK\n";
   }
	return 0;
}

Błąd:

g++ -c --std=c++11 -Wall main.cpp -I /rtr/rtr/temprepo/libs/headers/ -I ./
main.cpp: In function ‘int main(int, char**)’:
main.cpp52: error: invalid user-defined conversion from ‘int’ to ‘const string& {aka const std::basic_string<char>&}’ [-fpermissive]
Listener l(conf.get<int>(1, "NETWORK", "PORT"), conf.get<int>(1, "DEFAULT", "THREADS"));
^
In file included from /usr/include/c++/4.8.3/string0,
from /usr/include/c++/4.8.3/bits/locale_classes.h:40,
from /usr/include/c++/4.8.3/bits/ios_base.h:41,
from /usr/include/c++/4.8.3/ios:42,
from /usr/include/c++/4.8.3/ostream:38,
from /usr/include/c++/4.8.3/iostream:39,
from main.cpp
/usr/include/c++/4.8.3/bits/basic_string.h7: note: candidate is: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>] <near match="match">
basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
^
/usr/include/c++/4.8.3/bits/basic_string.h7: note: no known conversion for argument 1 from ‘int’ to ‘const char*’
main.cpp52: error: invalid conversion from ‘int’ to ‘const char*’ [-fpermissive]
Listener l(conf.get<int>(1, "NETWORK", "PORT"), conf.get<int>(1, "DEFAULT", "THREADS"));
^
In file included from /usr/include/c++/4.8.3/string0,
from /usr/include/c++/4.8.3/bits/locale_classes.h:40,
from /usr/include/c++/4.8.3/bits/ios_base.h:41,
from /usr/include/c++/4.8.3/ios:42,
from /usr/include/c++/4.8.3/ostream:38,
from /usr/include/c++/4.8.3/iostream:39,
from main.cpp
/usr/include/c++/4.8.3/bits/basic_string.h7: error: initializing argument 1 of ‘std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]’ [-fpermissive]
basic_string(const _CharT* __s, const _Alloc& __a = _Alloc());
^
make: *** [main.o] Błąd 1

DLaczego kompilator nie "widzi" ze ja chce parametryzować T jako int ? To mój czy jego błąd ??

0

btw.
g++ --version
g++ (GCC) 4.8.3 20140911 (Red Hat 4.8.3-7)

4

Pokaż definicję klasy Listener. Założę się, że konstruktor oczekuje std::string const& lub char const*

Przy okazji: zwracanie const T nie ma sensu

0

O kurcze, fakt ;d Listener oczekiwal stringa.

Natomiast pytanie, dlaczegonei ma sensu const T& ?

1

nie const T&, lecz const T
Z kopią niech sobie wszyscy robią co chcą, nie nasz interes

0

Odruchowo napisałem tę referencję, chodzi mi o to, żę const T jest ok, czy masz jakieś uwagi do takiego kodu ?

2

const przy typie zwracanym jest zbędne, wręcz szkodliwe:
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rf-out

It is not recommended to return a const value. Such older advice is now obsolete; it does not add value, and it interferes with move semantics.

throw()nothrow

trochę niekonsekwentny styl indentacji, do tego masakrycznie długa linia z sygnaturą get

Ale ogółem kod jest ładny, szczególnie biorąc pod uwagę dział.

1 użytkowników online, w tym zalogowanych: 0, gości: 1