Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Xarn
Jun 26, 2015

VikingofRock posted:

Actually wait why doesn't this work?

C++ code:
void molest(std::enable_if_t<impl::molest_by_increment_v<Iter>, Iter>& it)
{
    ++ it;
}

This form doesnt allow compiler to deduce Iter from callsite

Adbot
ADBOT LOVES YOU

VikingofRock
Aug 24, 2008




Xarn posted:

This form doesnt allow compiler to deduce Iter from callsite

Oohhhhh gotcha. Thanks.

hackbunny
Jul 22, 2007

I haven't been on SA for years but the person who gave me my previous av as a joke felt guilty for doing so and decided to get me a non-shitty av

Slurps Mad Rips posted:

C++ code:
// Using __LINE__ and an int here lets us not care about the generic signatures
// as long as only oneis unambiguously available at the end.
// Technically they could both be assigned to 0, but then a compiler error
// wouldn't let us know which culprits did what

oooh so that's what it's for

Slurps Mad Rips posted:

you can then turn that enable_if into a macro:

in my experience, macros and templates don't mix

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



god c++ is so freaking ugly :barf:

hackbunny
Jul 22, 2007

I haven't been on SA for years but the person who gave me my previous av as a joke felt guilty for doing so and decided to get me a non-shitty av
c++'s foundation is No New Syntax
a clearer syntax could break compatibility with c and old code
but, way more serious, it could break some clever trick someone came up with

it's sunk cost fallacy applied to language design

Nehacoo
Sep 9, 2011

Slurps Mad Rips posted:

you can then turn that enable_if into a macro: #define REQUIRE(...) std::enable_if_t<__VA_ARGS__, int> = __LINE__
and now you've got a clean lil' function

C++ code:
#define REQUIRE(...) std::enable_if_t<__VA_ARGS__, int> = __LINE__

namespace impl {
template <class T>
using iterator_category = typename std::iterator_traits<T>::iterator_category;
template <class T>
constexpr bool increment_v = not std::is_base_of_v<std::bidirectional_iterator_tag, iterator_category<T>>;
}

template <class Iter, REQUIRE(not impl::increment_v<Iter>)> void molest (Iter& it) { --it; }
template <class Iter, REQUIRE(impl::increment_v<Iter>)> void molest (Iter& it) { ++it; }

The macro approach is nice in my opinion, even though we're supposed to hate macros. It has a limitation, though, in that the condition passed to the macro must be related to a template parametre, otherwise it doesn't count as a substitution failure. This is relevant when you want to e.g. disable a member function in a class template depending on template parametre, but can be solved like this:

C++ code:
template <typename T>
class SomeClass {
	template <typename T_ = T, REQUIRES(std::is_integral<T_>::value)>
	void memberFunction() { /* ... */ } // Will only exist if T is an integer type
};


However, I've noticed that 99% of the time I use something like this, it is for checking type traits, so I made an alternative like this:

C++ code:
/** Conjunction of a variadic amount of type traits applied to type T.
 * `TraitConjunction<T, traits...>::value` is true if `trait<T>::value == true` for each trait.
 */
template
	< typename T
	, template<typename...> class Trait
	, template<typename...> class... Traits
	>
struct TraitConjunction {
	static constexpr bool value = Trait<T>::value && TraitConjunction<T, Traits...>::value;
};

template <typename T, template<typename...> class Trait>
struct TraitConjunction<T, Trait> {
	static constexpr bool value = Trait<T>::value;
};

/* TODO: replace with this C++17 implementation (I think this is valid):
template <typename T, template<typename...> typename... Traits>
struct TraitConjunction : std::integral_constant<bool, (Traits<T>::value &&...)> {};
*/

/** REQUIRES_TRAIT(type, traits...) enables overload only if trait<type>::value == true for each trait. */
#define REQUIRES_TRAIT(type, ...) \
	typename T_ = type, \
	std::enable_if_t<TraitConjunction<T_, ##__VA_ARGS__>::value, size_t> = __LINE__
Used like this:

C++ code:
template <typename T>
class SomeClass {
public:
	template <REQUIRES_TRAIT(T, std::is_integral)>
	void memberFunction() { /* ... */ } // Will only exist if T is an integer type
};
Obviously, the implementation of REQUIRES_TRAIT can be made a lot simpler if you only need to checking a single trait.
Also, ##__VA_ARGS__ is not standard, but seems to be available in all common compilers (at least Clang, GCC, MSVC).

My brain must be a bit broken because I think template meta-programming is actually fun.

Nehacoo fucked around with this message at 11:46 on Dec 2, 2016

hackbunny
Jul 22, 2007

I haven't been on SA for years but the person who gave me my previous av as a joke felt guilty for doing so and decided to get me a non-shitty av

Nehacoo posted:

It has a limitation, though, in that the condition passed to the macro must be related to a template parametre, otherwise it doesn't count as a substitution failure.

you fuckre that was my next post

hackbunny
Jul 22, 2007

I haven't been on SA for years but the person who gave me my previous av as a joke felt guilty for doing so and decided to get me a non-shitty av
if nothing else, I was successful in bringing out all the c++ victims out of the woodwork. I never knew you were so many!

Nehacoo
Sep 9, 2011

hackbunny posted:

you fuckre that was my next post

:mrgw:

hackbunny posted:

if nothing else, I was successful in bringing out all the c++ victims out of the woodwork. I never knew you were so many!

Victim? I chose this for myself!

redleader
Aug 18, 2005

Engage according to operational parameters
c++ is a terrible practical joke gone wrong

Nehacoo
Sep 9, 2011

redleader posted:

c++ is a terrible practical joke gone wrong

It's good

hackbunny
Jul 22, 2007

I haven't been on SA for years but the person who gave me my previous av as a joke felt guilty for doing so and decided to get me a non-shitty av
I wouldn't call it "good", but there isn't anything in the world like it

30 TO 50 FERAL HOG
Mar 2, 2005



holy lol c++ is even more dogshit than I thought

i didn't even think that was possible

leper khan
Dec 28, 2010
Honest to god thinks Half Life 2 is a bad game. But at least he likes Monster Hunter.

BiohazrD posted:

holy lol c++ is even more dogshit than I thought

i didn't even think that was possible

cool wrongpinion you have there
C++ is art

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

leper khan posted:

C++ is fart

Symbolic Butt
Mar 22, 2009

(_!_)
Buglord
I deeply agree with this post from the other thread:

Sapozhnik posted:

C++ is a tool for turning imaginary problems into real ones.
C++ is a tool where the most obvious answer to every single question is always wrong.
C++ lets you get high on your own farts creating all sorts of very clever nonsense that does achieve any practical goal whatsoever.

with that said, I love hackbunny's posts :allears:

Cybernetic Vermin
Apr 18, 2005

too weird to live, and too rare to die

Nehacoo
Sep 9, 2011

To be a bit more serious, all this crazy meta programming stuff we've been doing over the last few pages is not what 'normal' C++ code looks like (this is more like low-level generic library code).

No one seriously thinks the current methods for doing this stuff are desirable. There has for a long time been a proposal for a more sane and readable compile-time pattern matching system called concepts. It's supposed to make all template code clean, readable, give short and precise error messages, make sure template code is valid for all types it can be instantiated with, cure cancer, end all wars, etc.

However the committee cannot agree on how it should work so it will never make it into the standard, probably, but here's hoping for C++20 :thumbsup:

In the meantime, this is what we can do, unless we drop the whole compile-time meta-programming thing and do everything with runtime polymorphism like in other OOP languages. But that sucks because it requires dynamic allocation of objects (which is slow), vtable lookups (which easily causes branch misprediction), and indirection everywhere (which takes a steaming dump on data locality and thus performance). And that approach is closer what C++ was originally designed for, I believe. The template meta-programming stuff was accidental and discovered afterwards, concepts is supposed to replace it with an intentionally designed system.

fritz
Jul 26, 2003

Nehacoo posted:

To be a bit more serious, all this crazy meta programming stuff we've been doing over the last few pages is not what 'normal' C++ code looks like (this is more like low-level generic library code).

yeah this is getting deeply into 'don't do that it's gross'' mode

but one of the problems with c++ is that it's so easy to just do a little tmp and next thing you know

Sapozhnik
Jan 2, 2005

Nap Ghost

Nehacoo posted:

In the meantime, this is what we can do, unless we drop the whole compile-time meta-programming thing and do everything with runtime polymorphism like in other OOP languages. But that sucks because it requires dynamic allocation of objects (which is slow), vtable lookups (which easily causes branch misprediction), and indirection everywhere (which takes a steaming dump on data locality and thus performance). And that approach is closer what C++ was originally designed for, I believe. The template meta-programming stuff was accidental and discovered afterwards, concepts is supposed to replace it with an intentionally designed system.

Please don't take this as a personal attack but this is a perfect microcosm of the raging stupidity that begat ~*modern c++*~

If you're writing a numerical kernel or whatever that cares so deeply about performance that the behaviour of your branch predictor is a consideration (real time trading, codecs, the very innermost loops of a game engine), then the last thing you are going to want to do is poo poo out a bunch of insane template voodoo that is about five layers of impossible-to-mentally-model semantics removed from the metal. You're going to write raw C with raw memory accesses, vector intrinsics, and lots of compiler-specific pragmas and annotations. You are going to tailor it for one precise compiler, operating system, CPU target because your algorithm is business-critical and your particular choice of Xeon silicon is a real physical object that can execute the code and the phonebook sized printed C++ standard is not.

And of course this is going to be a tiny part of your code. There is no situation ever where micro-optimizing, say, your configuration file parser is a good idea.

hackbunny
Jul 22, 2007

I haven't been on SA for years but the person who gave me my previous av as a joke felt guilty for doing so and decided to get me a non-shitty av

Nehacoo posted:

No one seriously thinks the current methods for doing this stuff are desirable. There has for a long time been a proposal for a more sane and readable compile-time pattern matching system called concepts.

you mean, two (three?) competing and completely different proposals. and the worst one is gaining the most ground because it's the easiest to implement using the current metaprogramming hell and a sprinkling of compiler magic

meanwhile, on planet stroustrup: wouldn't it be cool if we could overload operator.??? no bjarne, it wouldn't

Wheany
Mar 17, 2006

Spinyahahahahahahahahahahahaha!

Doctor Rope

Sapozhnik posted:

There is no situation ever where micro-optimizing, say, your configuration file parser is a good idea.

Actually,

Xarn
Jun 26, 2015

hackbunny posted:

you mean, two (three?) competing and completely different proposals. and the worst one is gaining the most ground because it's the easiest to implement using the current metaprogramming hell and a sprinkling of compiler magic

meanwhile, on planet stroustrup: wouldn't it be cool if we could overload operator.??? no bjarne, it wouldn't

There are three now? Goddamit. Which one is winning?

Nehacoo
Sep 9, 2011

Sapozhnik posted:

Please don't take this as a personal attack but this is a perfect microcosm of the raging stupidity that begat ~*modern c++*~

If you're writing a numerical kernel or whatever that cares so deeply about performance that the behaviour of your branch predictor is a consideration (real time trading, codecs, the very innermost loops of a game engine), then the last thing you are going to want to do is poo poo out a bunch of insane template voodoo that is about five layers of impossible-to-mentally-model semantics removed from the metal. You're going to write raw C with raw memory accesses, vector intrinsics, and lots of compiler-specific pragmas and annotations. You are going to tailor it for one precise compiler, operating system, CPU target because your algorithm is business-critical and your particular choice of Xeon silicon is a real physical object that can execute the code and the phonebook sized printed C++ standard is not.

And of course this is going to be a tiny part of your code. There is no situation ever where micro-optimizing, say, your configuration file parser is a good idea.

Honestly, I am not experienced enough to know whether it's stupid or not. I'm just a student and hobbyist, and I've read the arguments for the modern C++ style and found them quite convincing.

Perhaps I'll change my mind in the future. But there is a level in between targeting specific CPUs, compilers, etc. and throwing runtime polymorphism all over the place. For example, being able to use std::vector for arbitrary types and get a contiguous storage while preserving non-POD semantics for contained objects is only possible thanks to templates. I would say the modern C++ style is about making it convenient and safe to use (nominally) zero-cost abstractions, even though the library implementations supporting it will look pretty nasty under the hood (see any STL implementation).

It's things like this talk which make me believe that modern C++ style can be brutally well optimised:

https://www.youtube.com/watch?v=zBkNBP00wJE

quote:

the very innermost loops of a game engine
That is what I'm doing, actually. We'll see how it goes!

hackbunny
Jul 22, 2007

I haven't been on SA for years but the person who gave me my previous av as a joke felt guilty for doing so and decided to get me a non-shitty av

Xarn posted:

There are three now? Goddamit. Which one is winning?

well, I assume there are three, or at least there have been three, because I remember a syntax where concepts looked like classes, that contained both pattern matching statements and extension methods (the intention being of allowing you to give a uniform api to all types that match a concept), and yet I can't find any mention of it anywhere anymore. I may have dreamed of it. it did look too good to be true

30 TO 50 FERAL HOG
Mar 2, 2005



hackbunny posted:

you mean, two (three?) competing and completely different proposals. and the worst one is gaining the most ground because it's the easiest to implement using the current metaprogramming hell and a sprinkling of compiler magic

meanwhile, on planet stroustrup: wouldn't it be cool if we could overload operator.??? no bjarne, it wouldn't

heres a cool factoid, soustrup taught my engr111 class at texas a&m "Foundations of Engineering"

it was bad

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

hackbunny posted:

and this is how enable_if is used! it can be used as an additional argument type (as we've done here), as a return type (can't be done here because the return type doesn't participate in overload resolution and we'd get a redefinition error),

fwiw, this isn't true. functions may not be overloaded by return type, but function templates can: the dependent components of the return type and template parameter list are part of the signature and do differentiate templates

Xarn
Jun 26, 2015
I cant be too hard on Stroustrup, he gave us my favourite language :v:

Also he wrote an interesting article about his experience teaching programming, that made me think harder about the course I teach.

Symbolic Butt
Mar 22, 2009

(_!_)
Buglord

Xarn posted:

I cant be too hard on Stroustrup, he gave us my favourite language :v:

Also he wrote an interesting article about his experience teaching programming, that made me think harder about the course I teach.

link to this article please, I have no idea what to expect from Stroustrup on teaching

gonadic io
Feb 16, 2011

>>=
certainly all this c++ talk has made me happy with my choice of rust as my next lang to learn.

distinguished unions, pattern matching, iterators, all with no runtime overhead like c++, but also a distinct lack of this incredible amount of bullshit (so far)

lifetimes annoyed me a lot at first, but then i started to realise that every compiler error would have been UB in C++ anyway

except for a few cases anyway, lexical lifetimes can't come soon enough

Slurps Mad Rips
Jan 25, 2009

Bwaltow!

hackbunny posted:

well, I assume there are three, or at least there have been three, because I remember a syntax where concepts looked like classes, that contained both pattern matching statements and extension methods (the intention being of allowing you to give a uniform api to all types that match a concept), and yet I can't find any mention of it anywhere anymore. I may have dreamed of it. it did look too good to be true

Concepts are now a technical specification

there is a proposal for 'virtual concepts' which is basically rust traits for use across shared libraries and a separate proposal for pattern matching based on type that you might be thinking of

i doubt those latter two would get past the committee if bjarne throws a tantrum again like he did with "if constexpr"

Cabbage Disrespect
Apr 24, 2009

ROBUST COMBAT
Leonard Riflepiss
Soiled Meat
my work is mostly scala these days and reading posts about c++ makes me say bizarre poo poo like "wow i'm glad i get to use such a simple and easy language"

brap
Aug 23, 2004

Grimey Drawer
honestly it makes me see the appeal of go because even though it's a language for retards at least you're not at risk of drowning in bikeshedding garbage and can focus on making stuff

fritz
Jul 26, 2003

Mr. Showtime posted:

my work is mostly scala these days and reading posts about c++ makes me say bizarre poo poo like "wow i'm glad i get to use such a simple and easy language"

im slowly trying to learn scala, and it's a flaw in my signed character that im drawn to complex rude languages like it, and before that c++ and before that perl

Sapozhnik
Jan 2, 2005

Nap Ghost

fleshweasel posted:

honestly it makes me see the appeal of go because even though it's a language for retards at least you're not at risk of drowning in bikeshedding garbage and can focus on making stuff

also true of python

although go is at least somewhat strongly typed

hmm

JewKiller 3000
Nov 28, 2006

by Lowtax

fritz posted:

flaw in my signed character

mods please

MononcQc
May 29, 2007

fleshweasel posted:

honestly it makes me see the appeal of go because even though it's a language for retards at least you're not at risk of drowning in bikeshedding garbage and can focus on making stuff

I still see discussions on whether you should bring in testing libraries that are not in the stdlib to have things like assertions in tests or just keep doing if err != nil everywhere and the language has existed for 7 years

Cabbage Disrespect
Apr 24, 2009

ROBUST COMBAT
Leonard Riflepiss
Soiled Meat

fritz posted:

im slowly trying to learn scala, and it's a flaw in my signed character that im drawn to complex rude languages like it, and before that c++ and before that perl

scala is loving rad given a p. strict code review process so that nobody can sneak their own pet DSL in (unless it's really slick) or write some undocumented method named @++%! without providing a named alternative, though in all fairness "it's not bad if you don't let people do bad things" applies to most languages

hackbunny
Jul 22, 2007

I haven't been on SA for years but the person who gave me my previous av as a joke felt guilty for doing so and decided to get me a non-shitty av

rjmccall posted:

fwiw, this isn't true. functions may not be overloaded by return type, but function templates can: the dependent components of the return type and template parameter list are part of the signature and do differentiate templates

alright, thanks. though I wonder for how long I will actually retain this information

Adbot
ADBOT LOVES YOU

Gazpacho
Jun 18, 2004

by Fluffdaddy
Slippery Tilde
no major numerical library relies on C++ for performance nor will they, seeing as they don't even rely on the C preprocessor

numerical library hackers are your ultimate "we live the hard life and we like it" crowd

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply