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
rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
template argument deduction matches the types of the arguments against the declared form of the parameters, trying to make them the same. if your template is declared like

code:
template <class T> void foo(T *);
and you pass it a const char * then template argument deduction will say aha, i can make those two types the same by assigning T = const char

but it does this purely by structurally decomposing the template parameter type in specific ways, so if instead you write:

code:
template <class T> void foo(typename identity<T>::type *);
then it has no idea how to make typename identity<T>::type be equal to const char, so it ignores that part of the match

this can be useful in your own templates. e.g. if you take two arguments and one is an l-value and the other is a value that you want to assign to it, you don't want to write your template like

code:
template <class T> void assign(T &dest, T value);
because a call like long l; assign(l, 0); will fail because template argument deduction occurs in parallel on all arguments, so it'll infer T = long from the first argument and T = int from the second, which causes a deduction failure and probably a completely incomprehensible compiler error. but here you can always infer T correctly from the first argument, so really you should suppress deduction in the second argument so that the argument will just be converted as appropriate:

code:
template <class T> void assign(T &dest, typename identity<T>::type value);

Adbot
ADBOT LOVES YOU

Xarn
Jun 26, 2015
This of course has the problem of potentially performing a costly conversion in addition to a copy (think assigning const char* to std::string) so you obviously have to template harder.

C++ code:
template <typename T, typename T2, typename = std::enable_if<std::is_assignable<T&, T2>::value>
void assign(T& dest, T2 src)
This now lets the second argument to be deduced separately, but only if T& can be assigned T2 (ie as already mentioned std::string& can be assigned const char*.)

So that eliminated the conversion if possible. Now how about copies? Well thats where perfect forwarding comes back.*
C++ code:
template <typename T, typename T2, typename = std::enable_if<std::is_assignable<T&, T2>::value>
void assign(T& dest, T&&2 src) {
    dest = std::forward<T>(src)
}
By changing the argument from T2 to T2&&, you get the actual referenceness (not a word afaik) of the argument given, thanks to the rules of reference collapsing. Then you use std::forward <T> to... forward the referenceness to the T's operator=.


Its important to remember that this doesn't work without the std::forward properly, because r-values really like to stop moving. Once you name them, even if you have r-value reference to a temporary, they are no longer moved automatically. This means that this

C++ code:
void move_to(std::string& dst, std::string&& from) {
    dst = from;
}

std::string a, b;
move_to(a, std::move(b));
actually copies b to a inside the move_to function. To fix it, you have to use move inside the move_to function as well.

C++ code:
void move_to(std::string& dst, std::string&& from) {
    dst = std::move(from); // now its fixed
}
And a little circle back a little , std::forward is implementable, and it is not THAT hard, this is the libc++ implementation (for C++11)
C++ code:
template <class T>
inline T&& forward(typename std::remove_reference<T>::type& t) noexcept
{
    return static_cast<T&&>(t);
}

template <class T>
inline T&& forward(typename std::remove_reference<T>::type&& t) noexcept
{
    static_assert(!std::is_lvalue_reference<T>::value,
                  "Can not forward an rvalue as an lvalue.");
    return static_cast<T&&>(t);
}
* Perfect forwarding with strings can also be a hilariously bad idea, in case you use the function with string literals, because then the function isn't deduced as
C++ code:
assign(std::string&, const char*)
but rather as
C++ code:
assign(std::string&, const char[4]);
assign(std::string&, const char[5]);
assign(std::string&, const char[6]);
...
---------------------
The above might not be entirely true, I haven't even had my first coffee, but it should be roughly correct.

brap
Aug 23, 2004

Grimey Drawer

Shaggar posted:

Microsoft was writing the best ui frameworks and languages 10 years ago.

wpf and winforms are basically abandoned except for critical fixes. all they really have for current poo poo is UWP and just lol at using UWP.

Shaggar
Apr 26, 2006

Soricidus posted:

only the last decade? what was better in 2005?

java was probably a better language back then


fleshweasel posted:

wpf and winforms are basically abandoned except for critical fixes. all they really have for current poo poo is UWP and just lol at using UWP.

winforms hasn't changed in years and uwp is wpf

Shaggar
Apr 26, 2006
uwp/wpf are also better than anything else as far as ui frameworks go

Bloody
Mar 3, 2013

isn't the only distinction between uwp and wpf the os you're running on?

Gul Banana
Nov 28, 2003

no

uwp is a reimplementation of wpf from scratch in c++, with some differences, both better and worse. for example: no support for control triggers, but it has a static alternative to bindings. they aren't compatible at all - you can't write code that is useful for both, though you can use standard techniques to have a model/business logic layer that's shared of course.

Gul Banana
Nov 28, 2003

uwp is pretty nice *as an api*. there are a few major hassles about it logistically though, all stemming from the bizarre choice to try and make .NET non-mandatory:
- controls are reference-counted not garbage collected, and it's easy to leak memory
- you can't publish components which reference non-COM types (!)
- debug builds and release builds use a totally different process, with release taking 10x longer and compiling to native code with semi-broken reflection. you have to test separately in both
- no controltriggers, only the silverlight-style visualstatemanager (which sucks imo)
and of course
- only works on windows 10

for business applications there is really no reason to switch to it.

Xarn
Jun 26, 2015

Shaggar posted:

uwp/wpf are also better than anything else as far as ui frameworks go

Why do then the new MS UWP apps suck so drat badly?

Cybernetic Vermin
Apr 18, 2005

Xarn posted:

Why do then the new MS UWP apps suck so drat badly?

i freely admit that i am an idiot and a sucker for being pointlessly different in having a w10m phone, but holy hell the few high effort uwp apps i have encountered have been fantastic. mail, calendar, the new skype, as well as minor stuff like the explorer app even. no idea if that is microsoft throwing excessive engineering resources on a bad framework, but they are certainly making the framework looking super-promising to me in a way the previous wpf variant never did v:shobon:v

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.
uwp is hot garbage that serves no purpose. nobody uses windows phone so uwp brings nobody new to the platform. if you already put up with wpf it is an entirely pointless reimplementation with zero attraction. having zero audience leads to decreasing support from microsoft and the death spiral of uwp

the worst that can be said about wpf is that it is competitive with ui frameworks on other platforms that have similar goals. if you have similar tastes as shaggar maybe it is the gold standard, if you're a little more circumspect it is merely fine

wpf can absolutely be improved, but uwp has no claim to that mantle. can't wait to see what the next lovely reimplementation of wpf looks like! we'll get it right this time! why is the silverlight team laughing at us?

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.
here is my example of pointless lovely reimplementation

this is the wpf tilebrush

this is the uwp tilebrush

are there any properties on the wpf one that seem oddly absent from the uwp one?

how about TileMode

you know, the property that controls how the contents are tiled

oh, we took that out of uwp?

so TileBrush doesn't tile

but we kept the class hierarchy for... convenience?

Malcolm XML
Aug 8, 2009

I always knew it would end like this.

pokeyman posted:

here is my example of pointless lovely reimplementation

this is the wpf tilebrush

this is the uwp tilebrush

are there any properties on the wpf one that seem oddly absent from the uwp one?

how about TileMode

you know, the property that controls how the contents are tiled

oh, we took that out of uwp?

so TileBrush doesn't tile

but we kept the class hierarchy for... convenience?

wpf and uwp are a product of microsofts divisions fighting each other

WinRT is like totally different to everything else. by design. sinofsky lmao

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
why does microsoft have like twenty different drawing apis

i still use GDI+ and it works fine

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.
but it's not totally different, that's my point. totally different might make sense

triple sulk
Sep 17, 2014



Malcolm XML posted:

wpf and uwp are a product of microsofts divisions fighting each other

WinRT is like totally different to everything else. by design. sinofsky lmao

dealing with 8.1 vs 10 can be a real pain in the rear end and i can confirm this because ive had to deal with it

Malcolm XML
Aug 8, 2009

I always knew it would end like this.

pokeyman posted:

but it's not totally different, that's my point. totally different might make sense

internally its totally different and they papered over the differences w/ whatever the gently caress uwp is

jony neuemonic
Nov 13, 2009

yeah ms continues to have one of the best web stacks imaginable but i have no clue what they're even aiming for on the desktop.

Xarn
Jun 26, 2015

Cybernetic Vermin posted:

i freely admit that i am an idiot and a sucker for being pointlessly different in having a w10m phone, but holy hell the few high effort uwp apps i have encountered have been fantastic. mail, calendar, the new skype, as well as minor stuff like the explorer app even. no idea if that is microsoft throwing excessive engineering resources on a bad framework, but they are certainly making the framework looking super-promising to me in a way the previous wpf variant never did v:shobon:v

The new skype for me

A) Doesnt send/receive chat messages to people I tried.
B) Doesnt show status of people (and people dont see my status either).

I guess it at least allows for calling people. (At least once we use different app to communicate being online :v:)


Now, I might just have a horrible case of "Doesn't work on my computer", but it doesn't inspire much confidence...

Cybernetic Vermin
Apr 18, 2005

have not seen that, i have switched over entirely, and have been very happy with it

not much to go by granted. otoh the complaint that microsoft has had a bad run of eol'ing stuff people like and use for a slightly different replacement is, while valid, sort of beside the point about uwp being good/bad

Gul Banana
Nov 28, 2003

Xarn posted:

Why do then the new MS UWP apps suck so drat badly?

a lot (most or all??) of the built in Windows 10 desktop store apps are actually written in html+javascript, which can call UWP APIs in a technically impressive but also insane way. the entire reason they made UWP is that the Windows division refuses to use C#.

jony neuemonic
Nov 13, 2009

Gul Banana posted:

the Windows division refuses to use C#.

oh my god.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

Gul Banana posted:

the entire reason they made UWP is that the Windows division refuses to use C#.

this explains so much

hobbesmaster
Jan 28, 2008

did they just look at C#/.net and say "hmmm this looks really straightforward, it's not an appropriate replacement for win32"

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

hobbesmaster posted:

did they just look at C#/.net and say "hmmm this looks really straightforward, it's not an appropriate replacement for win32"

you know what makes less sense but would make it easier for me to get a job in SF 8 months from now? javascript

hobbesmaster
Jan 28, 2008

this actually makes a lot of sense, especially considering MS's arbitrary firing practices

Malcolm XML
Aug 8, 2009

I always knew it would end like this.

hobbesmaster posted:

did they just look at C#/.net and say "hmmm this looks really straightforward, it's not an appropriate replacement for win32"

performance reasons made them do winrt, i.e. the revenge of COM, so that u could use C++

not a lot is in winjs iirc and it's basically dead

pokeyman posted:

this explains so much

reminder that most of windows 8 ui stuff was developed in secret and even devdiv didn't know a lot of it

Carthag Tuek
Oct 15, 2005

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



man i really did miss COM objects for a bit, thank god .Net has my rear end

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

Malcolm XML posted:

performance reasons made them do winrt, i.e. the revenge of COM, so that u could use C++

is .net core part of winrt or otherwise reliant on it? also wasn't there some other managed c++ thing before uwp's managed c++ thing? were those deemed insufficiently performant? it's not obvious to me that wpf etc. are fundamentally incapable of meeting performance goals but idk anything

also using uwp apps doesn't make me think "hot drat this performance is super keen". I assume that bet paid off handsomely in some other way. no doubt idiotic politics and pointless emphasis on programmer comfort are benefits that the end user can confidently expect to realize any decade now

redleader
Aug 18, 2005

Engage according to operational parameters

Gul Banana posted:

a lot (most or all??) of the built in Windows 10 desktop store apps are actually written in html+javascript, which can call UWP APIs in a technically impressive but also insane way.

this sounds juicy

Malcolm XML
Aug 8, 2009

I always knew it would end like this.

pokeyman posted:

is .net core part of winrt or otherwise reliant on it? also wasn't there some other managed c++ thing before uwp's managed c++ thing? were those deemed insufficiently performant? it's not obvious to me that wpf etc. are fundamentally incapable of meeting performance goals but idk anything

also using uwp apps doesn't make me think "hot drat this performance is super keen". I assume that bet paid off handsomely in some other way. no doubt idiotic politics and pointless emphasis on programmer comfort are benefits that the end user can confidently expect to realize any decade now

yeah but c++/cli was managed and c++/cx is unmanaged and this account for the screaming performance of winrt apps

also some guy wrote a modern CPP projection of the winrt stuff

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

Malcolm XML posted:

yeah but c++/cli was managed and c++/cx is unmanaged and this account for the screaming performance of winrt apps

I see

quote:

also some guy wrote a modern CPP projection of the winrt stuff

a what?

Malcolm XML
Aug 8, 2009

I always knew it would end like this.

pokeyman posted:

I see


a what?

yeah

Dr Monkeysee
Oct 11, 2002

just a fox like a hundred thousand others
Nap Ghost
[quote="rjmccall" post=""464854498"]
and you pass it a const char * then template argument deduction will say aha, i can make those two types the same by assigning T = const char

but it does this purely by structurally decomposing the template parameter type in specific ways, so if instead you write:

code:
template <class T> void foo(typename identity<T>::type *);
then it has no idea how to make typename identity<T>::type be equal to const char, so it ignores that part of the match
[/quote]

ah i see. because std::forward declares its parameter type using a typename member (in this case remove_reference), and type deduction only operates basically on syntax, it can't ever match so you're forced to be explicit.

Xarn posted:

* Perfect forwarding with strings can also be a hilariously bad idea, in case you use the function with string literals, because then the function isn't deduced as
C++ code:
assign(std::string&, const char*)
but rather as
C++ code:
assign(std::string&, const char[4]);
assign(std::string&, const char[5]);
assign(std::string&, const char[6]);
...

this… could be a problem for my log wrapper :ohdear:

Slurps Mad Rips
Jan 25, 2009

Bwaltow!

Xarn posted:

* Perfect forwarding with strings can also be a hilariously bad idea, in case you use the function with string literals, because then the function isn't deduced as
C++ code:
assign(std::string&, const char*)
but rather as
C++ code:
assign(std::string&, const char[4]);
assign(std::string&, const char[5]);
assign(std::string&, const char[6]);
...

dont forget when you perfectly forward a function that it won't decay to a function pointer, but will be treated as a function reference :v:

C++ code:
function(void(*ptr)()); // ok, this is "normal"
function(void(&ref)()); // that's the ticket!
function(void(&&ref)()); // BUT WAIT THERE'S MORE!
(All of this can be made "prettier" with type aliases)
C++ code:
template <class T> using fnptr = add_pointer_t<T>;
template <class T> using fnref = add_lvalue_reference_t<T>;
template <class T> using fnrref = add_rvalue_reference_t<T>;

function (fnptr<void()>);
function (fnref<void()>);
function (fnrref<void()>);
guess what happens here? (hint: the call is ambiguous because why the gently caress are you trying to differentiate between an rvalue reference to a function, an lvalue reference to a function, and a function pointer?!)
C++ code:
void test () { }

function(test);

Gul Banana
Nov 28, 2003

ok, this is technically actually interesting. WinRT is the successor to COM, right? it's an ABI, not language specific. winmd files (the same format as .net) replace IDL. you can use it like you would COM, with complex api call sequences and macros and templates in c++.. but that wouldn't be good enough for app authoring so they did a new thing: projections.

a winrt "projection" is a set of bindings and idioms which allow code in some specific target environment to *consume* and optionally *author* winrt components. so in the .NET project, winrt types appear as .net types and .net classes which meet certain restrictions can be read by winrt; similarly for c++/cx and for the javascript projection, winjs. winjs looks like this:

code:
(function () {
 'use strict';
 Debug.enableFirstChanceException(true);

 WinJS.Application.onmainwindowactivated=
 function (e) {
  if (e.detail.kind === 
   Windows.ApplicationModel.Activation.ActivationKind.launch) {
    // first-run code
  }
 }

 WinJS.Application.start();
})();
basically the namespaced WinRT components are viewed or 'projected' by JS as object property chains, and magic marshalling converts arguments back and forth. the components could be written in C++, visual basic, anything, and it still works. it's a pretty impressive piece of technical magic let down a bit by how it's useless and nobody wants it.

distortion park
Apr 25, 2011


Gul Banana posted:

ok, this is technically actually interesting. WinRT is the successor to COM, right? it's an ABI, not language specific. winmd files (the same format as .net) replace IDL. you can use it like you would COM, with complex api call sequences and macros and templates in c++.. but that wouldn't be good enough for app authoring so they did a new thing: projections.

a winrt "projection" is a set of bindings and idioms which allow code in some specific target environment to *consume* and optionally *author* winrt components. so in the .NET project, winrt types appear as .net types and .net classes which meet certain restrictions can be read by winrt; similarly for c++/cx and for the javascript projection, winjs. winjs looks like this:

code:
(function () {
 'use strict';
 Debug.enableFirstChanceException(true);

 WinJS.Application.onmainwindowactivated=
 function (e) {
  if (e.detail.kind === 
   Windows.ApplicationModel.Activation.ActivationKind.launch) {
    // first-run code
  }
 }

 WinJS.Application.start();
})();
basically the namespaced WinRT components are viewed or 'projected' by JS as object property chains, and magic marshalling converts arguments back and forth. the components could be written in C++, visual basic, anything, and it still works. it's a pretty impressive piece of technical magic let down a bit by how it's useless and nobody wants it.

that's pretty cool but I'd still rather be using wpf than anything it enables

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

pointsofdata posted:

that's pretty cool but I'd still rather be using wpf than anything it enables

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.
actually tho thanks for explaining. when I was doing a uwp app it seemed impossible to find anything about it in this level, it was all lovely marketing level "write once run everywhere" bs

Adbot
ADBOT LOVES YOU

raminasi
Jan 25, 2005

a last drink with no ice

Gul Banana posted:

it's a pretty impressive piece of technical magic let down a bit by how it's useless and nobody wants it.

ah, IJW interop's spiritual successor

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