Reputation: 591
Trying to compile the code below fails due to a "conflicting declaration". Why can't I define a forward declared class like this?
I did this to hide that the implementation uses a certain library. Although I'll admit that this does not really abstract anything - you'll still need to know what the implementation uses to make the correct call - I am still interested in why this doesn't work.
Bar.cpp:
#include "Bar.hpp"
#include "Foo.hpp"
using Foo = ns::Foo;
void Bar::foo(Foo f) {
}
Bar.hpp:
class Foo;
class Bar {
void foo(Foo f);
};
Foo.hpp:
namespace ns {
class Foo {
};
}
To be clear, I want to know why can't define a previously declared class by aliasing - in other words saying "use that definition over there that has a different name"
Upvotes: 1
Views: 1237
Reputation: 6194
You are declaring Foo
twice with conflicting types. First, you declare Foo
in Bar.hpp as:
class Foo;
Subsequently, you declare foo in Bar.cpp as:
using Foo = ns::Foo;
You cannot put a forward declaration like that if you define in your source file an alias with the same name, because then you declare two different types with the exactly the same name.
Based on your question I assume that you want to use Foo, without its namespace in the Bar.cpp. The solution is as following:
Bar.cpp
#include "Bar.hpp"
#include "Foo.hpp"
using ns::Foo;
void Bar::foo(Foo f) {}
Bar.hpp
namespace ns
{
class Foo;
}
class Bar
{
void foo(ns::Foo f);
};
Foo.hpp
namespace ns
{
class Foo
{};
}
Upvotes: 4
Reputation: 440
Because in order for the Bar::Foo
to work, the Bar class needs to know the size of the Foo argument as early as declaring it.
You could make this work, by declaring void foo(Foo* f);
That way, instead of knowing the size of Foo
, the compiler will only care for the size of a pointer.
Simply use to pick the namespace you need:
using namespace ns;
Upvotes: 0