1

I am trying to compile C++ code shown below but I got an error saying,

In file included from src/LM.h:3:0, from src/LM.cpp:1: src/common.h:30:13: error: ‘hash’ is already declared in this scope using tr1::hash;

This is the command I used to compile the files below.

g++ -std=c++11 -Wall src/Foo.cpp

Foo.cpp

#include "Foo.h"
...

Foo.h

#ifndef FOO_H
#define FOO_H
#include "common.h"
//more code here
#endif

common.h

#ifndef _COMMON_H_
#define _COMMON_H_

#include <iostream>
#include <fstream>
#include <cmath>
#include <cassert>
#include <cstdlib>
#include <utility>
#include <vector>
#include <string> 
#include <array>
#include <algorithm>
#include <set>
#include <tr1/unordered_map>
#include <tr1/functional>
namespace std {
    using tr1::unordered_map;
    using tr1::hash;
} // namespace std

using namespace std;

//more code here
#endif

I want the source code to use std::tr1::unordered_map and std::tr1::hash rather than std::unordered_map and std::hash(Actually I am making some modifications to distributed files which does uses std::tr1::unordered_map and std::tr1::hash).

What is possibly wrong with my codes?

UPD: https://github.com/clab/fast_align/blob/master/src/port.h seems to do the same thing as mine. However, this compiles without any problem... Have any idea?

hitochan
  • 1,028
  • 18
  • 34
  • 1
    Out of interest why do you want to use `std::tr1::hash` instead of `std::hash`? – sjdowling Oct 28 '14 at 10:23
  • 1
    That `port.h` compiles because it doesn't include ``, which declares the real `std::hash`. – Lightness Races in Orbit Oct 28 '14 at 10:25
  • The source code I am modifying is using std::tr1::hash so I am just following it because I am not familiar with these stuffs. Is there any big difference? – hitochan Oct 28 '14 at 10:25
  • @HitoshiOtsuki: You should be changing that code to use `std::hash`, not hacking the heck out of your standard library to try to replace `std::hash` with `std::tr1::hash`. – Lightness Races in Orbit Oct 28 '14 at 10:26
  • 3
    This is why we don't do `using namespace std;`. If you're trying to modify code that uses `tr1::hash`, it's better and less hacky to do a grep/search-and-replace than what you're attempting to do. –  Oct 28 '14 at 10:27
  • @Lightness Races in Orbit Do you mean once the std::hash is included, it is impossible to overwrite std::hash with std::tr1::hash? – hitochan Oct 28 '14 at 10:30
  • 2
    @HitoshiOtsuki: Once you have introduced a name into a program you cannot throw it away and replace it with something else, no. And, again, you really shouldn't be mauling your standard library implementation like this. Use `std::hash` as provided. – Lightness Races in Orbit Oct 28 '14 at 10:31
  • I see :) thanks you all for your useful comments. – hitochan Oct 28 '14 at 10:33

1 Answers1

5

There is already std::hash in C++11. You cannot redefine it. You can use another name for tr1::hash.

Probably the best idea (if you really want to use std::tr1::hash/std::tr1::unordered_map instead of C++11 structures) is to write your own namespace in which using all structures, that you want without std::hash/std::unordered_map.

namespace common
{

using std::tr1::hash;
using std::tr1::unordered_map;
using std::vector;
// and so on

}
ForEveR
  • 55,233
  • 2
  • 119
  • 133
  • Thanks :) If std::hash doesn't differ much from std::tr1::hash, I will just use std::hash. – hitochan Oct 28 '14 at 10:34
  • `std::hash` and `std::tr1::hash` should be the same thing on a C++11 implementation; I would be very astonished if they weren't! – LThode Oct 28 '14 at 17:09
  • @LThode If so, why are there two implementations which are the same? – hitochan Oct 29 '14 at 01:42
  • @HitoshiOtsuki: History. `std::tr1::hash` came first with the Technical Report 1 to C++98/03. When C++11 came around, the TR1 standard library additions became full-fledged Standard Library classes, hence `std::hash`. – LThode Nov 05 '14 at 21:24