writing.exchange is one of the many independent Mastodon servers you can use to participate in the fediverse.
A small, intentional community for poets, authors, and every kind of writer.

Administered by:

Server stats:

326
active users

#cplusplus

2 posts1 participant0 posts today

I know I follow a lot of indie game makers here, but I have little idea of what engines any of of you use. Anybody here know about C++ compiling? @josemachete79 is working on building his own version of #Angband from a cloned repo, and is running into issues compiling.

Any help anyone can offer would be much appreciated- I've played a test build or two of the game and it's working great except for these final compiling issues. Hit him up!

(The image below is a screenshot of the starting character I randomly generated to use when testing one of the builds.)

Sandor Dargo’s Blog · Should you use final?Today, let’s discuss a bit about the not too frequently used final specicfier. I think there is not a lot of reason to use which is supported by the core guidelines. But even when you’d use it, probably you should not. Today, let’s discuss the not-too-frequently-used final specifier. I think there aren’t many good reasons to use it — something the C++ Core Guidelines also suggests. And even when you could use it, you probably shouldn’t. final is not a keyword, “only” an “identifier with special meaning”. Technically, it can be used as a name for objects or functions, but it can have a special meaning if used at the right place. If you want readable code though, don’t use it as an identifier! final is not technically a keyword, it’s an “identifier with special meaning”. It can be used as a name for objects or functions, but if used in the right place, it gains special behavior. For readable code, though, don’t use it as an identifier! Let’s start with a quick recap of the final specifier, then move on to a nasty example I recently ran into. What is final In C++, final is a specifier used to prevent further derivation or overriding. It can be applied to both classes and virtual functions. final classes When final is applied to a class, it prevents other classes from inheriting from it. 1 2 3 4 5 6 class Base {}; class Derived final : public Base {}; // OK class AnotherDerived : public Derived {}; // Error! Derived is final final virtual functions When final is applied to a virtual function, it prevents derived classes from overriding it. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Base { public: virtual void foo() {} // void bar() final {} // error: only virtual member functions can be marked 'final' }; class Derived : public Base { public: void foo() final {} }; class AnotherDerived : public Derived { // void foo() override {} // error: foo() is marked final in Derived }; It’s worth noting that you cannot mark a non-virtual function as final. When to use it? Don’t use final a lot. More than that, use it less than you probably would! The Core Guidelines talks about final usage in two rules. C.139 says that you should use final on classes sparingly. The reason? It’s rarely needed for logical reasons and can hurt the extensibility of your class hierarchies. Some claim that marking classes final improves performance, but that’s more of an urban legend — or at least only true in specific cases. As always: measure. In the next section, I’ll show how a final class can be too limiting. Before that, let’s briefly mention the other rule, C.128. It says that (virtual) functions should specify exactly one of virtual, override or final. Using only one is explicit and precise: virtual -> “this is a new virtual function”. override -> “this is a non-final overrider” final -> “this is a final overrider.” Though you should use final on functions just as sparignly as on classes. Don’t use final on mocks! Recently, I was cleaning up the outputs of a test harness. To reduce noise, I decided to wrap a mock class with NiceMock<T>. If you set no expectations on a mocked call, but it’s invoked, the test harness will report “uninteresting calls”. Using NiceMock<T> suppresses those. If you use StrictMock<T>, uninteresting calls will cause test failures. Look for more info here. When I tried to compile, it failed! After some wondering and digging, I discovered that NiceMock<T> and StrictMock<T> both inherit from T. In fact, they use the CRTP design pattern. So, if you try to use NiceMock<T> on a class T that has been marked final then the compilation will fail, because NiceMock cannot inherit from T. Too bad… If you have the rights to change the source code of T, good for you. Go ahead and consider remove final from class declaration. If you cannot do that, you might ask the owners to do so or you simply have to give up on using NiceMock. Nevertheless, if you are using gmock and you are writing some mock classes, don’t mark then final. Don’t make life harder for your users or for yourself. Conclusion In this article, we talked about the final specifier. You can use it on classes and member functions to prevent inheritance and overrides, respectively. While it may seem useful at first glance, it doesn’t offer performance benefits in most cases—and it often just adds unnecessary constraints. That’s why the Core Guidelines recommend using it sparingly. We saw a concrete example where marking a mock class as final prevented its use with NiceMock<T> or StrictMock<T>, since they inherit from the mock class behind the scenes. Connect deeper If you liked this article, please hit on the like button, subscribe to my newsletter

Hey I'm still looking for work.
I've applied to a lot of places in my area and I'm getting nothing.

I'm a programmer at heart, but I've also been looking for regular entry-level jobs because there haven't been any coding positions open at my level as far as I could tell.

If you can offer me a job, it might save my butt. And if you can't offer me a job, could you at least share this post?

I live 30 minutes away from Bellevue if that helps.

Sandor Dargo’s Blog · C++26: variadic friendsUp until C++23, functions, classes, function and class templates could be declared as friends. Starting from C++26, thanks to Jody Hagins’ and Arthur O’Dwyer’s proposal, P2893R3, friendship can also be granted to a pack of types. Who does a pack of friends look like? In earlier standards, we must declare friend class templates one by one, just like in the example below. 1 2 3 4 5 6 template<class T=void, class U=void> class Foo { friend T; friend U; }; Note the default values for the template parameters. That makes it possible to accept a variadic number of template arguments with the maximum number of arguments fixed by how many parameters we added. With C++26, that is simplified and you can directly use a pack of types with friendship granted. 1 2 3 4 template<class... Ts> class Foo { friend Ts...; }; Now let’s see two practical usages from the proposal. The Passkey idiom If you ever used friends you might have found it problematic that a friend declaration’s scope is for the whole class. If you declare a friend within a class, it will have access to all the private parts of the class. But what if you wanted to limit the access to a couple of member functions? One option is to move those to another class and grant friendship within that class. Though it’s highly probable that from a design perspective that’s not such a great idea. Another - more elegant solution - is the passkey idiom. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 template<class T> class Passkey { friend T; Passkey() = default; // note that this ctor is private! }; class A; class B; class C { friend A; private: void internal(); public: void intentionalA(Passkey<A>); void intentionalB(Passkey<B>); }; class A { void m(C& c) { c.internal(); // OK c.intentionalA({}); // OK c.intentionalB({}); // Error, Passkey<B>'s constructor is inaccessible } }; class B { void m(C& c) { c.intentionalB({}); // OK } }; You can see that in order to call C’s public functions, you need to pass a Passkey object specialized with the right class. But only T can instantiate Passkey<T> due to its private constructor combined with friendship. It seems a bit cumbersome that you need two different member functions if you want to give access to two different classes, intentionalA for A and intentionalB for B. The name could be the same, but you’d still need two function bodies (definitions) and you’d have to type out the Passkeys to avoid ambiguous function calls: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 template<class T> class Passkey { friend T; Passkey() {} }; class A; class B; class C { friend A; private: void internal(); public: void intentional(Passkey<A>); void intentional(Passkey<B>); }; class A { void m(C& c) { c.internal(); // OK c.intentional(Passkey<A>{}); // OK c.intentional(Passkey<B>{}); // Error, Passkey<B>'s ctor is inaccessible } }; class B { void m(C& c) { c.intentional(Passkey<B>{}); // OK } }; With variadic friends, this code can be simplified. We have to make Passkey accept a variadic number of arguments and make them all friends. Then C::intentional can accept any allowed specialization. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 template<class... T> class Passkey { friend T...; Passkey() {} }; class A; class B; class C { friend A; private: void internal(); public: void intentional(Passkey<A, B>); }; class A { void m(C& c) { c.internal(); // OK c.intentional({}); // OK } }; class B { void m(C& c) { c.intentional({}); // OK } }; It’s worth noting that you don’t need access to a class’ constructor to use it as a template type parameter. Passkey<A, B>{} works fine for both A and B. With this change, you only need to define intentional once. CRTP and access to private parts of derived classes If you are not familiar with the Curiously Recurring Template Pattern (CRTP), read this article before moving on. When you use this pattern, it might happen that in the base class, you want to access private parts of the derived class. As you don’t want to expose those private parts, you grant friendship to the base class. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 // The base class template<class Crtp, class MsgT> class Receiver { void receive(MsgT) { static_cast<Crtp*>(this)->private_ += 1; } }; // The derived class template<class MsgT> struct Dispatcher : public Receiver<Dispatcher<MsgT>, MsgT> { //_private member exposed to the base class, called Receiver using Receiver<Dispatcher, MsgT>::Receiver; friend Receiver<Dispatcher, MsgT>; private: int private_; }; Fair enough. But what if there are several base classes? What if the Dispatcher takes a variadic number of message types, inheriting from a pack of base classes? Today, there is no nice and simple solution, because only inheritance and the using directive support pack expansion, but not friendships. With C++26, the solution is simple, because friendship can be granted to a pack of friends. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 // The base class template<class Crtp, class MsgT> class Receiver { void receive(MsgT) { static_cast<Crtp*>(this)->private_ += 1; } }; // The derived class template<class... MsgTs> // notice the variadic template parameters struct Dispatcher : public Receiver<Dispatcher<MsgTs...>, MsgTs>... // Inheritance supports pack expansion { using Receiver<Dispatcher, MsgTs>::Receiver...; // The using directive support pack expansion friend Receiver<Dispatcher, MsgTs>...; // Error pre-C++26, accepted from C++26 private: int private_; }; Conclusion Thanks to the acceptance of P2893R3, friendship can also be granted to a pack of types. While you won’t need this feature every day, as you can see from the examples, in the right circumstances, it can significantly simplify your code. Connect deeper If you liked this article, please hit on the like button, subscribe to my newsletter

Ok, I guess I'll do an #introduction on this account now:

I'm Eleanor, a software engineer working mostly in #cplusplus and #rust these days. My background is in math, physics, and scientific computing, but I'm currently moving into a new thing that's still programming in Rust and C++, but in a very different domain than what I'm used to (and for a lot more users).

When I'm not staring at text on a screen or managing other aspects of my life, I play the violin and the piano, and I read science fiction and fantasy books. These are few and far between these days since there's always a lot going on.

This account is intended to focus mostly on my computer-related escapades.

I have run this exercise with multiple C++ developers from junior to senior. Its a simple task that can reveal strength/weakness in a devs understanding of what good C++ could look like.

Implement a reverse words function that works in-place on the string provided.
- Make it correct
- Make it performant
- Make it maintainable

Give it a go. I'll also post content warning hint(s) as replies.

godbolt.org/z/9faxG7K4b

godbolt.orgCompiler Explorer - C++ (x86-64 clang 17.0.1) void reverse_words(std::string &) noexcept { // Implement here } int main() { using namespace std::string_literals; auto str = "Can you reverse these words?"s; reverse_words(str); assert(str == "words? these reverse you Can"); }