I think the private/public might be a problem. I would expect from compiler error about redeclaration. But if you switched back to public, I'd be OK with that.
I'd prefer to see a larger proposal for allowing a separate forward declaration of the public interface of a class from the definition of the class.
If you believe as I do that the part of the gradual movement towards left-to-right declarations is a recognition that a name should be introduced before being described then you will understand my philosophy of Doxygen markup.
On 2015-11-15 05:24, Andrew Tomazos wrote:
> I think there is a good idea in here.
>
> Rather than making this narrow change, I'd prefer to see a larger proposal
> for allowing a separate forward declaration of the public interface of a
> class from the definition of the class.
>
> Perhaps something like:
>
> public class MyClass {
> MyClass(int = 0);
>
> int val() const;
> void val(int);
> };
>
> class MyClass {
> public:
> MyClass(int = 0) { ... }
>
> int val() const { ... }
> void val(int) { ... }
>
> private:
> int val_;
> };
I don't think this will work. The size of the class needs to be known
publicly. Adding NSDM's after the fact will break things. (And adding
any other members opens a can of worms to abuse / circumvention of
access protections.)
In fact, I have trouble seeing how your suggestion is in any meaningful
way an improvement over what we have now. All you've really accomplished
is adding a closing brace before the private members. That may look
pretty, but it hardly seems worth a non-trivial change to both syntax
and semantics.
On 2015-11-16 13:58, Andrew Tomazos wrote:
> For example, take a look at any of the class definitions of the containers
> in any standard library implementation.
>
> They are 1000+ lines long and even the public sections (plural) are 90%
> implementation details.
And why do you expect your proposal to "fix" this? That problem exists
because library writers *don't care*.
One small issue I have with this is the current method lets you put includes that only the inline functions rely on after the class declaration. With this proposal this isn't possible.
The only way this case could work is with the "interface" idea:
public class MyClass {
MyClass(int = 0);
int val() const;
void val(int);
};
// put includes here
class MyClass {
public:
MyClass(int = 0) { ... }
int val() const { ... }
void val(int) { ... }
private:
int val_;
};
Although I don't like that syntax. Not sure what would be best for that.
Example:
class MyClass
{
public:
MyClass(int = 0);
int val() const;
void set_val(int);
private:
int m_val;
};
// place "private" includes here
namespace class MyClass
{
MyClass(int) { ... }
int val() const { ... }
void set_val(int) { ... }
}
template <class Ch, class Tr>
class String {
public:
void some_method();
void another_method();
};
template <class Ch, class Tr>
void String<Ch, Tr>::some_method() {
// ...
}
template <class Ch, class Tr>
void String<Ch, Tr>::another_method() {
// ...
}
template <class Ch, class Tr>
class String {
public:
void some_method();
};
template <class Ch, class Tr>
namespace class String {
void some_method() {
// ...
}
void another_method() {
// ...
}
}
--
template <class Ch, class Tr>
namespace class String {
void member() {}
}
template <class Ch, class Tr>
void String<Ch, Tr>::member() {}
// typical class declaration
template <class Ch, class Tr>
class String {
public:
String(Ch ch);
void some_method();
void another_method();
static String strch(Ch ch);
};
// non-inline definition using proposed syntax
template<class Ch, class Tr>
namespace class String { /* I'm ok with any keyword besides "namespace" */
String(Ch ch) {
// ...
}
void some_method() {
// ...
}
void another_method() {
// ...
}
String strch(Ch) {
// ...
}
}
template <class Ch, class Tr>
String<Ch, Tr>::String(Ch ch) {
// ...
}
template <class Ch, class Tr>
void String<Ch, Tr>::some_method() {
// ...
}
template <class Ch, class Tr>
void String<Ch, Tr>::another_method() {
// ...
}
template <class Ch, class Tr>
String<Ch, Tr> String<Ch, Tr>::strch(Ch) {
// ...
}
template <class T>
class MyClass {
public:
template <class U>
void member(U u);
};
// current syntax (yuck)
template <class T> // did i get the ordering right, I always forget!
template <class U>
void MyClass<T>::member(U u) {
// ...
}
// proposed syntax, no room for mistakes, much clearer
template <class T>
namespace class MyClass {
template <class U>
void member(U u) {
// ..
}
}
Sure. Syntax is open for discussion; I agree the "namespace class" is
potentially dubious (partly why I originally wrote "<block scope>"
rather than suggesting an actual syntax).
I agree with Matthew here about access specifier, I don't think it is useful (or simpler) to have a separate scope for each access type. As Matthew said, it's not a c++ namespace, but it is a namespace in the colloquial English sense, so it's not like it is complete nonsense.
Perhaps this would be a good place to re-use the now defunct export keyword or similar? (I would have actually favored "extern" more since the definition of of the functions are "external". But yea, generically something like this is what I would prefer.
Another option would be to introduce a context sensitive keyword which strikes me as a lot more viable if we were to add a new one. For example (scope being the example):template <...> class : scope <identifier> {}
I agree with Matthew here about access specifier, I don't think it is useful (or simpler) to have a separate scope for each access type. As Matthew said, it's not a c++ namespace, but it is a namespace in the colloquial English sense, so it's not like it is complete nonsense.
Perhaps this would be a good place to re-use the now defunct export keyword or similar? (I would have actually favored "extern" more since the definition of of the functions are "external". But yea, generically something like this is what I would prefer.[ template <...> ] <keyword> class <identifier> { ... }
Also note, that I removed the semicolon at the end. This isn't declaring a class, it is defining methods of an already defined class. Similar to how namespace doesn't require the semicolon.
Assuming you mean that as a syntax for my proposal, I don't like it. It
violates DRY (making you repeat the access specification), and requires
a separate scope block for each access level.
FWIW, I disagree that a class is not a namespace. I mean, obviously it's
not exactly a "namespace" (C++ keyword), but it is a name scope (i.e.
"name space" in colloquial English).