0

I am completely out of ideas why the following example template will fail to compile on C++11 (gcc 4.9.2). For some reason, compiler requires me to call string() on already a string object that is being passed as variables_map.at() parameter. Note, that variables_map.count() takes the same argument in it's "pure" form with no objections.

One more observation: if the function is not a template but declared for specific type T, it compiles fine with no errors.

Here's the sample code:

#include <boost/program_options.hpp>
#include <iostream>
#include <map>
#include <utility>
#include <string>

namespace po = boost::program_options;

template <typename T> void test_error(T par, po::variables_map vm) {
    std::multimap<T, std::string> mm;
    mm.emplace(std::make_pair(par, "test"));

    auto a_range = mm.equal_range(par);
    for (auto it = a_range.first; it != a_range.second; ++it) {
        std::cout << vm.count(std::string(it->second)) << std::endl; //OK
        std::cout << vm.count(           (it->second)) << std::endl; //OK

        std::cout << vm.at(std::string(it->second)).as<T>() << std::endl; //OK
        std::cout << vm.at(            it->second ).as<T>() << std::endl; //COMPILE ERROR
    }
}

And compiler errors:

error: expected primary-expression before ‘>’ token
std::cout << vm.at(            it->second) .as<T>() << std::endl; //COMPILE ERROR
                                                ^
error: expected primary-expression before ‘)’ token
std::cout << vm.at(            it->second) .as<T>() << std::endl; //COMPILE ERROR
                                                  ^
Marcin L
  • 73
  • 10
  • 1
    CLang advised to insert `template` into line: `vm.at( it->second ).template as< T >()` . now compiler is OK (both CLang and GCC). It is making me crazy. Could you provide `main()` to test this ? Can anybody explain, why `template` is needed here? – Ivan Apr 15 '16 at 02:08
  • 1
    @Ivan http://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-the-template-and-typename-keywords It's required here because the names are dependent on template arguments – sehe Apr 15 '16 at 17:02
  • @sehe thank you. I need learn c+++ deeper – Ivan Apr 15 '16 at 18:45
  • @sehe but why then you don't need `template` keyword in the previous line i.e. `vm.at(std::string(it->second)).as()`? – Marcin L Apr 15 '16 at 20:09
  • Not looking at the code, the logical explanation would be: because it's meaning doesn't depend on a template parameter. Note that MSVC is notorious for non conforming lookup implementations around this theme. So if you're using MSVC you could be seeing code accepted that it should not accept – sehe Apr 15 '16 at 21:25

0 Answers0