Search code examples
c++boost

C++ ambiguous symbol error


I'm building Quantlib using Boost libraries in VS2013. I built Boost using NuGet package manager in VS2013.

I am getting 50 instances of ambiguous symbol error in my build. All the errors are related to the same variable: tolerance . Below is a sample cpp file where the variable is declared and then accessed. I get errors in lines 51,77, and 98, the three instance where the variable tolerance is used.

The namespace is defined without any namespace_name and there is no using namespace namespace_name; line. I don't know if this is an issue or if the issue is something else. I am a total newb with C++ so I will appreciate any help to fix this.

#include "tqreigendecomposition.hpp"
#include "utilities.hpp"
#include <ql/math/matrixutilities/tqreigendecomposition.hpp>

using namespace QuantLib;
using namespace boost::unit_test_framework;

namespace {

    Real tolerance = 1.0e-10;

}


void TqrEigenDecompositionTest::testEigenValueDecomposition() {
    BOOST_TEST_MESSAGE("Testing TQR eigenvalue decomposition...");

    Array diag(5);
    Array sub(4,1);
    diag[0]=11; diag[1]=7; diag[2]=6; diag[3]=2; diag[4]=0;
    Real ev[5] = {11.2467832217139119,
                  7.4854967362908535,
                  5.5251516080277518,
                  2.1811760273123308,
                  -0.4386075933448487};

    TqrEigenDecomposition tqre(diag, sub,
                               TqrEigenDecomposition::WithoutEigenVector);
    for (Size i=0; i < diag.size(); ++i) {
        const Real expected(ev[i]);
        const Real calculated(tqre.eigenvalues()[i]);
        if (std::fabs(expected-calculated) > tolerance) {
            BOOST_FAIL(std::string("wrong eigenvalue \n")
                       << "calculated: "
                       << calculated
                       <<" expected  : "
                       << expected);
        }
    }
}

void TqrEigenDecompositionTest::testZeroOffDiagEigenValues() {
    BOOST_TEST_MESSAGE("Testing TQR zero-off-diagonal eigenvalues...");

    Array diag(5);
    Array sub(4,1);
    sub[0] =sub[2]=0;
    diag[0]=12; diag[1]=9; diag[2]=6; diag[3]=3; diag[4]=0;

    TqrEigenDecomposition tqre1(diag, sub);

    sub[0]=sub[2]=1e-14;
    TqrEigenDecomposition tqre2(diag, sub);

    for (Size i=0; i < diag.size(); ++i) {
        const Real expected(tqre2.eigenvalues()[i]);
        const Real calculated(tqre1.eigenvalues()[i]);
        if (std::fabs(expected-calculated) > tolerance) {
            BOOST_FAIL(std::string("wrong eigenvalue \n")
                       << "calculated: "
                       << calculated
                       << " expected  : "
                       << expected);
        }
    }
}

void TqrEigenDecompositionTest::testEigenVectorDecomposition() {
    BOOST_TEST_MESSAGE("Testing TQR eigenvector decomposition...");

    Array diag(2,1);
    Array sub(1,1);

    TqrEigenDecomposition tqre(diag, sub);

    if (std::fabs(0.25 + tqre.eigenvectors()[0][0]
                       * tqre.eigenvectors()[0][1]
                       * tqre.eigenvectors()[1][0]
                       * tqre.eigenvectors()[1][1]) > tolerance) {
        BOOST_FAIL("wrong eigenvector");
    }
}

test_suite* TqrEigenDecompositionTest::suite() {
    test_suite* suite = BOOST_TEST_SUITE("TQR eigendecomposition tests");
    suite->add(QUANTLIB_TEST_CASE(
                   &TqrEigenDecompositionTest::testEigenValueDecomposition));
    suite->add(QUANTLIB_TEST_CASE(
                   &TqrEigenDecompositionTest::testZeroOffDiagEigenValues));
    suite->add(QUANTLIB_TEST_CASE(
                   &TqrEigenDecompositionTest::testEigenVectorDecomposition));
    return suite;
}

EDIT 1

Full error text (copied from the error list window in VS2013) I'll look to see if there is a log file somewhere that contains more detail.

Error   2   error C2872: 'tolerance' : ambiguous symbol C:\Users\wb459349\QuantLib-1.6\test-suite\tqreigendecomposition.cpp 52  1   testsuite

 tqreigendecomposition.cpp
1>tqreigendecomposition.cpp(52): error C2872: 'tolerance' : ambiguous symbol
1>          could be 'tqreigendecomposition.cpp(30) : QuantLib::Real `anonymous-namespace'::tolerance'
1>          or       'tolerance'

Ok so 'tolerance' is defined twice. Once inside the code with the 'anonymous-namespace' and not sure what the second 'tolerance' is, perhaps in one of the two namespaces that whomever built this Quantlib file has invoked when the did the "using namespace ..."


Solution

  • As @n.m. said avoid using namespace you likely have local/member variables that conflict with those of other libraries.

    Example:

    using namespace std
    ...
    cout << "Foo" << endl;
    

    is more ambiguous than

    ...
    std::cout << "Foo" << std::endl;
    

    In summary you have two options.

    1. Find all local/member variables that might conflict with those in the included libraries and update them.
    2. Or two (the preferred method) stop using using namespace and update all references to use the :: scope resolution operator.

    Edit:

    I think generally the advice to not use using is sound. However, in this particular instance my answer might not be the best advice. As others have mentioned these errors originate within a third-party library and as such it is probably better to point out this incompatibility to the author of this library.