By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,406 Members | 2,660 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,406 IT Pros & Developers. It's quick & easy.

Template and Namespace Ambiguity Issue

P: n/a
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.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Jun 19 '07 #1
Share this Question
Share on Google+
6 Replies


P: n/a
bo*******@yahoo.com wrote:
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
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 19 '07 #2

P: n/a
LR
bo*******@yahoo.com wrote:
[snippage]
>
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

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

Jun 20 '07 #3

P: n/a
bo*******@yahoo.com wrote:
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! ]

Jun 20 '07 #4

P: n/a
In article <11**********************@q75g2000hsh.googlegroups .com>,
<bo*******@yahoo.comwrote:
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 Tstruct 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

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

Jun 20 '07 #5

P: n/a
template <typename T>
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 Tvoid 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.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Jun 20 '07 #6

P: n/a
bo*******@yahoo.com wrote:
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;
}

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

Jun 20 '07 #7

This discussion thread is closed

Replies have been disabled for this discussion.