multiple definition of `operator<<(std::ostream&, Error const&)'

Hello

Please, help me! This code from the book: Professional C++ By Nicholas A. Solter, Scott J. Kleper. I redistributed it in different files.

Error.h:44: multiple definition of `operator<<(std::ostream&, Error const&)'


Error.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/* 
 * File:   Error.h
 * Author: Ivan
 *
 * Created on March 27, 2013, 8:07 PM
 */

#ifndef ERROR_H
#define	ERROR_H

#include <ostream>
#include <string>
using namespace std;

// Sample Error class with just a priority and a string error description

class Error {
public:

    Error(int priority, std::string errMsg) :
    mPriority(priority), mError(errMsg) {
    }

    int getPriority() const {
        return mPriority;
    }

    std::string getErrorString() const {
        return mError;
    }

    friend bool operator<(const Error& lhs, const Error& rhs);
    friend ostream& operator<<(ostream& str, const Error& err);

protected:
    int mPriority;
    std::string mError;
};

bool operator<(const Error& lhs, const Error& rhs) {
    return (lhs.mPriority < rhs.mPriority);
}

ostream& operator<<(ostream& str, const Error& err) {
    str << err.mError << " (priority " << err.mPriority << ")";
    return (str);
}

#endif	/* ERROR_H */ 


ErrorCorrelator.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/* 
 * File:   ErrorCorrelator.h
 * Author: Ivan
 *
 * Created on March 29, 2013, 12:24 PM
 */

#ifndef ERRORCORRELATOR_H
#define	ERRORCORRELATOR_H

#include <queue>
#include <stdexcept>
#include "Error.h"

// Simple ErrorCorrelator class that returns highest priority errors first

class ErrorCorrelator {
public:

    ErrorCorrelator() {
    }
    //
    // Add an error to be correlated.
    //
    void addError(const Error& error);
    //
    // Retrieve the next error to be processed.
    //
    Error getError() throw (std::out_of_range);

protected:
    std::priority_queue<Error> mErrors;

private:
    // Prevent assignment and pass-by-reference.
    ErrorCorrelator(const ErrorCorrelator& src);
    ErrorCorrelator& operator=(const ErrorCorrelator& rhs);
};

#endif	/* ERRORCORRELATOR_H */ 


ErrorCorrelator.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/* 
 * File:   ErrorCorrelator.cpp
 * Author: Ivan
 * 
 * Created on March 29, 2013, 12:24 PM
 */

#include "ErrorCorrelator.h"
#include "Error.h"
using namespace std;

void ErrorCorrelator::addError(const Error& error) {
    mErrors.push(error);
}

Error ErrorCorrelator::getError() throw (out_of_range) {
    //
    // If there are no more errors, throw an exception.
    //
    if (mErrors.empty()) {
        throw (out_of_range("No elements!"));
    }
    // Save the top element.
    Error top = mErrors.top();
    // Remove the top element.
    mErrors.pop();
    // Return the saved element.
    return (top);
}


main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/* 
 * File:   main.cpp
 * Author: Ivan
 *
 * Created on March 27, 2013, 8:07 PM
 */

#include <iostream>
using namespace std;

#include "ErrorCorrelator.h"
#include "Error.h"

int main(int argc, char** argv) {
    ErrorCorrelator ec;
    ec.addError(Error(3, "Unable to read file"));
    ec.addError(Error(1, "Incorrect entry from user"));
    ec.addError(Error(10, "Unable to allocate memory!"));
    while (true) {
        try {
            Error e = ec.getError();
            cout << e << endl;
        } catch (out_of_range&) {
            cout << "Finished processing errors\n";
            break;
        }
    }
    return (0);
}


Thank you!
Last edited on
The problem is that this operator definition

1
2
3
4
ostream& operator<<(ostream& str, const Error& err) {
    str << err.mError << " (priority " << err.mPriority << ")";
    return (str);
}


is placed by you in a header file. So if the header is included in more than one module you will have several definitions of the operator.
The simplest way to escape the error is to define the function as inline

For example

1
2
3
4
inline ostream& operator<<(ostream& str, const Error& err) {
    str << err.mError << " (priority " << err.mPriority << ")";
    return (str);
}

Last edited on
But now:

OutPut from NetBeans:


"/usr/bin/make" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf
make[1]: Entering directory `/d/_____Work/ErrorCorrelator'
"/usr/bin/make"  -f nbproject/Makefile-Debug.mk dist/Debug/MinGW-Windows/errorcorrelator.exe
make[2]: Entering directory `/d/_____Work/ErrorCorrelator'
mkdir -p build/Debug/MinGW-Windows/_ext/268615399
rm -f build/Debug/MinGW-Windows/_ext/268615399/ErrorCorrelator.o.d
g++    -c -g -MMD -MP -MF build/Debug/MinGW-Windows/_ext/268615399/ErrorCorrelator.o.d -o 
build/Debug/MinGW-Windows/_ext/268615399/ErrorCorrelator.o /D/_____Work/ErrorCorrelator/ErrorCorrelator.cpp
mkdir -p build/Debug/MinGW-Windows
rm -f build/Debug/MinGW-Windows/main.o.d
g++    -c -g -MMD -MP -MF build/Debug/MinGW-Windows/main.o.d -o build/Debug/MinGW-Windows/main.o main.cpp
mkdir -p dist/Debug/MinGW-Windows
g++     -o dist/Debug/MinGW-Windows/errorcorrelator build/Debug/MinGW-Windows/_ext/268615399/ErrorCorrelator.o 
build/Debug/MinGW-Windows/main.o 
build/Debug/MinGW-Windows/main.o: In function `ZltRK5ErrorS1_':
D:\_____Work\ErrorCorrelator/Error.h:40: multiple definition of `operator<(Error const&, Error const&)'
build/Debug/MinGW-Windows/_ext/268615399/ErrorCorrelator.o:d:/_____Work/ErrorCorrelator/Error.h:40: first 
defined here collect2: ld returned 1 exit status
make[2]: *** [dist/Debug/MinGW-Windows/errorcorrelator.exe] Error 1
make[2]: Leaving directory `/d/_____Work/ErrorCorrelator'
make[1]: *** [.build-conf] Error 2
make[1]: Leaving directory `/d/_____Work/ErrorCorrelator'
make: *** [.build-impl] Error 2


BUILD FAILED (exit value 2, total time: 3s)
Last edited on
I see that the same problem exists for operator
multiple definition of `operator<(Error const&, Error const&)'
So you can also define it as inline or place all your function definitions in some module removing them from the header.
Last edited on
So you can also define it as inline


I did it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/* 
 * File:   Error.h
 * Author: Ivan
 *
 * Created on March 27, 2013, 8:07 PM
 */

#ifndef ERROR_H
#define	ERROR_H

#include <ostream>
#include <string>
using namespace std;

// Sample Error class with just a priority and a string error description

class Error {
public:

    Error(int priority, std::string errMsg) :
    mPriority(priority), mError(errMsg) {
    }

    int getPriority() const {
        return mPriority;
    }

    std::string getErrorString() const {
        return mError;
    }

    friend bool operator<(const Error& lhs, const Error& rhs);
    friend ostream& operator<<(ostream& str, const Error& err);

protected:
    int mPriority;
    std::string mError;
};

bool operator<(const Error& lhs, const Error& rhs) {
    return (lhs.mPriority < rhs.mPriority);
}

inline ostream& operator<<(ostream& str, const Error& err) {
    str << err.mError << " (priority " << err.mPriority << ")";
    return (str);
}

#endif	/* ERROR_H */ 


But it doesn't work
Last edited on
or place all you function definitions in some module removing them from the header


And it doesn't work.

Error.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/* 
 * File:   Error.h
 * Author: Ivan
 *
 * Created on March 27, 2013, 8:07 PM
 */

#ifndef ERROR_H
#define	ERROR_H

#include <ostream>
#include <string>
using namespace std;

// Sample Error class with just a priority and a string error description

class Error {
public:

    Error(int priority, std::string errMsg) :
    mPriority(priority), mError(errMsg) {
    }

    int getPriority() const {
        return mPriority;
    }

    std::string getErrorString() const {
        return mError;
    }

    friend bool operator<(const Error& lhs, const Error& rhs);
    friend ostream& operator<<(ostream& str, const Error& err);

protected:
    int mPriority;
    std::string mError;
};

bool operator<(const Error& lhs, const Error& rhs) {
    return (lhs.mPriority < rhs.mPriority);
}

#endif	/* ERROR_H */ 


Error.cpp
1
2
3
4
5
6
#include "Error.h"

ostream& operator<<(ostream& str, const Error& err) {
    str << err.mError << " (priority " << err.mPriority << ")";
    return (str);
}


Output:

"/usr/bin/make" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf
make[1]: Entering directory `/d/_____Work/ErrorCorrelator'
"/usr/bin/make"  -f nbproject/Makefile-Debug.mk dist/Debug/MinGW-Windows/errorcorrelator.exe
make[2]: Entering directory `/d/_____Work/ErrorCorrelator'
mkdir -p build/Debug/MinGW-Windows/_ext/268615399
rm -f build/Debug/MinGW-Windows/_ext/268615399/Error.o.d
g++    -c -g -MMD -MP -MF build/Debug/MinGW-Windows/_ext/268615399/Error.o.d -o 
build/Debug/MinGW-Windows/_ext/268615399/Error.o /D/_____Work/ErrorCorrelator/Error.cpp
mkdir -p build/Debug/MinGW-Windows/_ext/268615399
rm -f build/Debug/MinGW-Windows/_ext/268615399/ErrorCorrelator.o.d
g++    -c -g -MMD -MP -MF build/Debug/MinGW-Windows/_ext/268615399/ErrorCorrelator.o.d -o 
build/Debug/MinGW-Windows/_ext/268615399/ErrorCorrelator.o /D/_____Work/ErrorCorrelator/ErrorCorrelator.cpp
mkdir -p build/Debug/MinGW-Windows
rm -f build/Debug/MinGW-Windows/main.o.d
g++    -c -g -MMD -MP -MF build/Debug/MinGW-Windows/main.o.d -o build/Debug/MinGW-Windows/main.o main.cpp
mkdir -p dist/Debug/MinGW-Windows
g++     -o dist/Debug/MinGW-Windows/errorcorrelator build/Debug/MinGW-Windows/_ext/268615399/Error.o 
build/Debug/MinGW-Windows/_ext/268615399/ErrorCorrelator.o build/Debug/MinGW-Windows/main.o 
build/Debug/MinGW-Windows/_ext/268615399/ErrorCorrelator.o: In function `ZltRK5ErrorS1_':
d:/_____Work/ErrorCorrelator/Error.h:40: multiple definition of `operator<(Error const&, Error const&)'
build/Debug/MinGW-Windows/_ext/268615399/Error.o:d:/_____Work/ErrorCorrelator/Error.h:40: first defined here
build/Debug/MinGW-Windows/main.o: In function `ZltRK5ErrorS1_':
D:\_____Work\ErrorCorrelator/Error.h:40: multiple definition of `operator<(Error const&, Error const&)'
build/Debug/MinGW-Windows/_ext/268615399/Error.o:d:/_____Work/ErrorCorrelator/Error.h:40: first defined here
collect2: ld returned 1 exit status
make[2]: *** [dist/Debug/MinGW-Windows/errorcorrelator.exe] Error 1
make[2]: Leaving directory `/d/_____Work/ErrorCorrelator'
make[1]: *** [.build-conf] Error 2
make[1]: Leaving directory `/d/_____Work/ErrorCorrelator'
make: *** [.build-impl] Error 2


BUILD FAILED (exit value 2, total time: 4s)

Last edited on
I do not see that you did it for operator

bool operator<(const Error& lhs, const Error& rhs) {
return (lhs.mPriority < rhs.mPriority);
}
I compiled this project in Visual C++ 2010 Express

Output:
1>------ Build started: Project: ErrorCorrelator, Configuration:
Debug Win32 ------
1>  main.cpp

1>c:\users\ivan\documents\visual studio 2010\projects\errorcorrelator\
errorcorrelator.h(29): warning C4290: C++ exception specification ignored 
except to indicate a function is not __declspec(nothrow)

1>  ErrorCorrelator.cpp
1>c:\users\ivan\documents\visual studio 2010\projects\errorcorrelator\
errorcorrelator.h(29): warning C4290: C++ exception specification ignored 
except to indicate a function is not __declspec(nothrow)
1>c:\users\ivan\documents\visual studio 2010\projects\errorcorrelator\
errorcorrelator.cpp(16): warning C4290: C++ exception specification ignored 
except to indicate a function is not __declspec(nothrow)
1>  Error.cpp
1>  Generating Code...
1>ErrorCorrelator.obj : error LNK2005: "bool __cdecl operator<(class Error const &,
class Error const &)" (??M@YA_NABVError@@0@Z) already defined in Error.obj
1>main.obj : error LNK2005: "bool __cdecl operator<(class Error const &,class 
Error const &)" (??M@YA_NABVError@@0@Z) already defined in Error.obj
1>C:\Users\Ivan\Documents\Visual Studio 2010\Projects\ErrorCorrelator\Debug\
ErrorCorrelator.exe : fatal error LNK1169: one or more multiply defined symbols found
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========


Error.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/* 
 * File:   Error.h
 * Author: Ivan
 *
 * Created on March 27, 2013, 8:07 PM
 */

#ifndef ERROR_H
#define	ERROR_H

#include <ostream>
#include <string>
using namespace std;

// Sample Error class with just a priority and a string error description

class Error {
public:

    Error(int priority, std::string errMsg) :
    mPriority(priority), mError(errMsg) {
    }

    int getPriority() const {
        return mPriority;
    }

    std::string getErrorString() const {
        return mError;
    }

    friend bool operator<(const Error& lhs, const Error& rhs);
    friend ostream& operator<<(ostream& str, const Error& err);

protected:
    int mPriority;
    std::string mError;
};

bool operator<(const Error& lhs, const Error& rhs) {
    return (lhs.mPriority < rhs.mPriority);
}

#endif	/* ERROR_H */ 


Error.cpp
1
2
3
4
5
6
#include "Error.h"

ostream& operator<<(ostream& str, const Error& err) {
    str << err.mError << " (priority " << err.mPriority << ")";
    return (str);
}


ErrorCorrelator.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/* 
 * File:   ErrorCorrelator.h
 * Author: Ivan
 *
 * Created on March 29, 2013, 12:24 PM
 */

#ifndef ERRORCORRELATOR_H
#define	ERRORCORRELATOR_H

#include <queue>
#include <stdexcept>
#include "Error.h"

// Simple ErrorCorrelator class that returns highest priority errors first

class ErrorCorrelator {
public:

    ErrorCorrelator() {
    }
    //
    // Add an error to be correlated.
    //
    void addError(const Error& error);
    //
    // Retrieve the next error to be processed.
    //
    Error getError() throw (std::out_of_range);

protected:
    std::priority_queue<Error> mErrors;

private:
    // Prevent assignment and pass-by-reference.
    ErrorCorrelator(const ErrorCorrelator& src);
    ErrorCorrelator& operator=(const ErrorCorrelator& rhs);
};

#endif	/* ERRORCORRELATOR_H */ 


ErrorCorrelator.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/* 
 * File:   ErrorCorrelator.cpp
 * Author: Ivan
 * 
 * Created on March 29, 2013, 12:24 PM
 */

#include "ErrorCorrelator.h"
#include "Error.h"
using namespace std;

void ErrorCorrelator::addError(const Error& error) {
    mErrors.push(error);
}

Error ErrorCorrelator::getError() throw (out_of_range) {
    //
    // If there are no more errors, throw an exception.
    //
    if (mErrors.empty()) {
        throw (out_of_range("No elements!"));
    }
    // Save the top element.
    Error top = mErrors.top();
    // Remove the top element.
    mErrors.pop();
    // Return the saved element.
    return (top);
}


Please, help me!
Last edited on
I already said what you should to do. Please reread my messages.
vlad from moscow, thanks very much! ( Огромное спасибо :) )

1)

Error.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/* 
 * File:   Error.h
 * Author: Ivan
 *
 * Created on March 27, 2013, 8:07 PM
 */

#ifndef ERROR_H
#define	ERROR_H

#include <ostream>
#include <string>
using namespace std;

// Sample Error class with just a priority and a string error description

class Error {
public:

    Error(int priority, std::string errMsg) :
    mPriority(priority), mError(errMsg) {
    }

    int getPriority() const {
        return mPriority;
    }

    std::string getErrorString() const {
        return mError;
    }

    friend bool operator<(const Error& lhs, const Error& rhs);
    friend ostream& operator<<(ostream& str, const Error& err);

protected:
    int mPriority;
    std::string mError;
};

#endif	/* ERROR_H */ 


Error.cpp
1
2
3
4
5
6
7
8
9
10
#include "Error.h"

ostream& operator<<(ostream& str, const Error& err) {
    str << err.mError << " (priority " << err.mPriority << ")";
    return (str);
}

bool operator<(const Error& lhs, const Error& rhs) {
    return (lhs.mPriority < rhs.mPriority);
}


2)

Error.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/* 
 * File:   Error.h
 * Author: Ivan
 *
 * Created on March 27, 2013, 8:07 PM
 */

#ifndef ERROR_H
#define	ERROR_H

#include <ostream>
#include <string>
using namespace std;

// Sample Error class with just a priority and a string error description

class Error {
public:

    Error(int priority, std::string errMsg) :
    mPriority(priority), mError(errMsg) {
    }

    int getPriority() const {
        return mPriority;
    }

    std::string getErrorString() const {
        return mError;
    }

    friend bool operator<(const Error& lhs, const Error& rhs);
    friend ostream& operator<<(ostream& str, const Error& err);

protected:
    int mPriority;
    std::string mError;
};

inline ostream& operator<<(ostream& str, const Error& err) {
    str << err.mError << " (priority " << err.mPriority << ")";
    return (str);
}

inline bool operator<(const Error& lhs, const Error& rhs) {
    return (lhs.mPriority < rhs.mPriority);
}

#endif	/* ERROR_H */ 
Topic archived. No new replies allowed.