Template and Namespace Ambiguity Issue

V

Victor Bazarov

Hi All

Given the following:

// NamespaceTemplate.cpp : Defines the entry point for the console
application.
//

#include "stdafx.h"

namespace N1
{
class C1
{
public:
void f() {}
void g() {}
};

class C2
{
public:

typedef C1 buddy;
void h(C1 info) {}
void i() {}
};
}

namespace N2
{
class C1
{
public:
void f() {}
void g() {}
};

class C2
{
public:


typedef C1 buddy;
void h(C1 info) {}
void i() {}
};
}

template <typename T>
void k(T x)
{
C1 theProblem; // Ambiguous!! How to create the correct object???

typename T::buddy theProblem;
x.h(theProblem);
x.i();
}

using namespace N1;
using namespace N2;

Do you really need those 'using' directives here?
int main(int argc, char* argv[])
{
N1::C2 b;
k(b); // Invoke Template function

N2::C2 d;
k(d); // Invoke Template function

return 0;
}

What is the best way (that is, the most common way) to resolve the
issue above? I get an ambiguous symbol error when compiling, which
does make sense. I'm looking for a way to resolve this without
resorting to passing in enumerated types representing objects or
something like that.

V
 
B

bogus1one

Hi All

Given the following:

// NamespaceTemplate.cpp : Defines the entry point for the console
application.
//

#include "stdafx.h"

namespace N1
{
class C1
{
public:
void f() {}
void g() {}
};

class C2
{
public:
void h(C1 info) {}
void i() {}
};
}

namespace N2
{
class C1
{
public:
void f() {}
void g() {}
};

class C2
{
public:
void h(C1 info) {}
void i() {}
};
}

template <typename T>
void k(T x)
{
C1 theProblem; // Ambiguous!! How to create the correct object???
x.h(theProblem);
x.i();
}

using namespace N1;
using namespace N2;
int main(int argc, char* argv[])
{
N1::C2 b;
k(b); // Invoke Template function

N2::C2 d;
k(d); // Invoke Template function

return 0;
}

What is the best way (that is, the most common way) to resolve the
issue above? I get an ambiguous symbol error when compiling, which
does make sense. I'm looking for a way to resolve this without
resorting to passing in enumerated types representing objects or
something like that.

Thanks.
 
L

LR

What is the best way (that is, the most common way) to resolve the
issue above?

I don't know the best way, or even the most common way.
I'm looking for a way to resolve this without
resorting to passing in enumerated types representing objects or
something like that.


Would this work for you?

I added some stuff to see what happens when I run.

#include <iostream>
#include <string>

void m(const std::string &s) { std::cout << s << std::endl; }

namespace N1
{
class C1
{
public:
void f() {m("N1::C1::f");}
void g() {m("N1::C1::g");}
};

class C2
{
public:
void h(C1 info) { info.g(); m("N1::C2::h");}
void i() {m("N1::C2::i");}
};

template<typename T>
void k(T x) {
C1 theProblem;
::k(x, theProblem);
}
}

namespace N2
{
class C1
{
public:
void f() {m("N2::C1::f");}
void g() {m("N2::C1::g");}
};

class C2
{
public:
void h(C1 info) {info.g(); m("N2::C2::h");}
void i() {m("N2::C2::i");}
};

template<typename T>
void k(T x) {
C1 theProblem;
::k(x, theProblem);
}
}

template<typename T1, typename T2>
void k(T1 x, const T2 &theProblem) {
x.h(theProblem);
x.i();
}

int main()
{
N1::C2 b;
k(b);

N2::C2 d;
k(d);

}

LR
 
C

Carl Barron

Hi All

Given the following:

// NamespaceTemplate.cpp : Defines the entry point for the console
application.
//

#include "stdafx.h"

namespace N1
{
class C1
{
};

class C2
{
};
}

namespace N2
{
class C1
{
};

class C2
{
};
}

template <typename T>
void k(T x)
{
C1 theProblem; // Ambiguous!! How to create the correct object???
// ...
}

using namespace N1;
using namespace N2;
int main(int argc, char* argv[])
{
N1::C2 b;
k(b); // Invoke Template function

N2::C2 d;
k(d); // Invoke Template function

return 0;
}

What is the best way (that is, the most common way) to resolve the
issue above? I get an ambiguous symbol error when compiling, which
does make sense. I'm looking for a way to resolve this without
resorting to passing in enumerated types representing objects or
something like that.

Thanks.

The obvious is template <class U,class T>
void k(T x)
{
U theproblem;
` // etc.
}

int main()
{
// ...
k<N1::C1>(b);
// ...
k<N2::C1>(b);
}

or you can create a meta function that calculates the type of the
problem from the argument type:

template <class T> struct problem;
template <> struct problem<N1::C2> {typedef N1::C1 type;};
template <> struct problem<N2::C2> {typedef N2::C1 type;};

template <class T>
void k(T x)
{
problem<T>::type theProblem;
// as original without the C1 theProblem declaration.
}

original main code
 
R

Roman.Perepelitsa

template said:
void k(T x)
{
C1 theProblem; // Ambiguous!! How to create the correct object???
x.h(theProblem);
x.i();

}

It's not ambigous, C1 is just undeclared.

C1 does not depend on template parameter => it should be declared
before the definition of template <typename T> void k(T x). This
function template definition is illegal even if you never instantiate
it.

There are plenty possible solutions to your problem. Here is one of
them.

namespace N1
{
class C1
{
public:
void f() {}
void g() {}
};


class C2
{
public:
typedef C1 Info;
void h(Info info) {}
void i() {}
};
}


namespace N2
{
class C1
{
public:
void f() {}
void g() {}
};

class C2
{
public:
typedef C1 Info;
void h(Info info) {}
void i() {}
};
}

template <typename T>
void k(T x)
{
typename T::Info theProblem;
x.h(theProblem);
x.i();
}


int main(int argc, char* argv[])
{
N1::C2 b;
k(b);

N2::C2 d;
k(d);

return 0;
}

Roman Perepelitsa.
 
U

Ulrich Eckhardt

namespace N1
{
class C1
{
public:
void f() {}
void g() {}
};

class C2
{
public:
void h(C1 info) {}
void i() {}
};
}

namespace N2
{
class C1
{
public:
void f() {}
void g() {}
};

class C2
{
public:
void h(C1 info) {}
void i() {}
};
}

template <typename T>
void k(T x)
{
C1 theProblem; // Ambiguous!! How to create the correct object???
x.h(theProblem);
x.i();
}

Well, what I would perhaps do is define what the correct object is! My guess
is that you want to call this function with either an N2::C2 or an N1::C2,
right? In that case, I see two options:
1. You specialise the function.
2. You introduce a typedef, nested into the C1s, which declares the correct
C2:
template<typename T>
void foo(T x) {
typename T::c1_t theSolution;
x.h(theSolution);
}
using namespace N1;
using namespace N2;

Eww, first this...
int main(int argc, char* argv[])
{
N1::C2 b;

....and then this? What's the point of separating things in namespaces if you
afterwards throw everything together again?
What is the best way (that is, the most common way) to resolve the
issue above? I get an ambiguous symbol error when compiling, which
does make sense.

Hmmm, errors about symbols are typically linker errors. It would be helpful
to quote error message. It would also have helped if you had trimmed your
example, e.g. the i() is completely unnecessary (I think).

Uli

--
Sator Laser GmbH
Geschäftsführer: Ronald Boers, Amtsgericht Hamburg HR B62 932


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 
F

Fei Liu

Hi All

Given the following:

// NamespaceTemplate.cpp : Defines the entry point for the console
application.
//

#include "stdafx.h"

namespace N1
{
class C1
{
public:
void f() {}
void g() {}
};

class C2
{
public:
void h(C1 info) {}
void i() {}
};
}

namespace N2
{
class C1
{
public:
void f() {}
void g() {}
};

class C2
{
public:
void h(C1 info) {}
void i() {}
};
}

template <typename T>
void k(T x)
{
C1 theProblem; // Ambiguous!! How to create the correct object???
x.h(theProblem);
x.i();
}

using namespace N1;
using namespace N2;
int main(int argc, char* argv[])
{
N1::C2 b;
k(b); // Invoke Template function

N2::C2 d;
k(d); // Invoke Template function

return 0;
}

What is the best way (that is, the most common way) to resolve the
issue above? I get an ambiguous symbol error when compiling, which
does make sense. I'm looking for a way to resolve this without
resorting to passing in enumerated types representing objects or
something like that.

Thanks.
This works for me and is pretty generic imo:
template <typename T, class C>
void k(T x)
{
C theProblem; // Ambiguous!! How to create the correct object???
x.h(theProblem);
x.i();
}

using namespace N1;
using namespace N2;
int main(int argc, char* argv[])
{
N1::C2 b;
k<N1::C2, N1::C1>(b); // Invoke Template function

N2::C2 d;
k<N2::C2, N2::C1>(d); // Invoke Template function

return 0;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,113
Latest member
Vinay KumarNevatia
Top