Why does the Microsoft implementation of concept std::output_iterator<It,T> contain a cast of type T? - c++20

Ranges are complete in VS2019, see https://devblogs.microsoft.com/cppblog/c20-ranges-are-complete-in-visual-studio-2019-version-16-10/
Why does the output_iterator concept have a static cast in the definition below taken from the Microsoft implementation?
// CONCEPT output_iterator
template <class _It, class _Ty>
concept output_iterator = input_or_output_iterator<_It> && indirectly_writable<_It, _Ty>
&& requires(_It __i, _Ty&& __t) {
*__i++ = static_cast<_Ty&&>(__t);
};
The definition on cppreference contains no such cast.

Related

Convert an instance of QObject to JSON

I have some code that I am using to convert arbitrary QObject subclasses to JSON. I able to convert them if they are pointers to a subclass, but am curious whether it is possible to convert instances (provided the subclass implements a copy constructor). Is there some crazy way to use something like templates or the type information provided by QMetaType to copy an instance of a QObject subclass without knowing what it is? The ToJson code is in a class that has no knowledge of the subclass.
I think it might be possible with QMetaType::create or something similar but I haven't been able to figure out how to actually copy the properties of the subclass instance.
Here's my code for converting:
QJsonValue ToJson(QVariant value){
switch(value.type()){
case QVariant::Int:
case QVariant::Double:
return value.toDouble();
////Other cases, etc...
case QVariant::UserType:
QObject* obj_ptr = qvariant_cast<QObject*>(value);
if(obj_ptr) // value was originally a pointer to a QObject, works correctly
return ToJson(obj_ptr);
else { // value was orginally an instance of a QObject subclass
std::string t = value.typeName(); //returns "MyQObject"
int id = QMetaType::type(t.c_str()); //returns the id of the derived class
void* v = QMetaType::create(id, &value); //passing &value does nothing
obj_ptr = static_cast<QObject*>(v);
return ToJson(obj_ptr); //works, but resulting fields are all default
}
}
}
QJsonObject ToJson(QObject* o){
QJsonObject obj;
auto mo = o->metaObject();
for (int i = mo->propertyOffset(); i < mo->propertyCount(); ++i){
QVariant value = o->property(mo->property(i).name());
obj[mo->property(i).name()] = ToJson(value);
}
return obj;
}
Sample code use case:
qRegisterMetaType<MyQObject>();
MyQObject obj;
obj.db = 11.1;
QVariant test1 = QVariant::fromValue(obj);
QVariant test2 = QVariant::fromValue(&obj);
QJsonValue v1 = ToJson(test1); // default constructed values
QJsonValue v2 = ToJson(test2); // db = 11.1
Sample QObject subclass:
class MyQObject : public QObject {
Q_OBJECT
Q_PROPERTY(double DB MEMBER db)
Q_PROPERTY(int I MEMBER i)
public:
MyQObject();
MyQObject(const MyQObject& other) : QObject() {
i = other.i;
db = other.db;
}
int i = 50;
double db = 1.5;
};
Q_DECLARE_METATYPE(MyQObject)
Is there any way to handle the case illustrated by test1 above?
Long-story-short: nope. There is no way to store QObjects by value in containers or QVariant.
Qt forbids the copy of QObjects and all inheriting classes. The mandatory the Q_OBJECT macro will disable any copy constructor also in newly defined classes.
The copy constructor that you are defining in the MyObject class is missing the base class constructor call. If QObject had a copy constructor it would be something like this:
MyQObject(const MyQObject& other) :
QObject(other) // this will NEVER compile
{
i = other.i;
db = other.db;
}
Probably, the compiler is giving you a warning, but allows you to have such a constructor, even if it will result in undefined behavior or slicing an instance of MyObject every time it is passed by value.
Furthermore, the Qt docs states the following:
The values stored in the various containers can be of any assignable
data type. To qualify, a type must provide a default constructor, a
copy constructor, and an assignment operator. This covers most data
types you are likely to want to store in a container, including basic
types such as int and double, pointer types, and Qt data types such as
QString, QDate, and QTime, but it doesn't cover QObject or any QObject
subclass (QWidget, QDialog, QTimer, etc.).
So you can't store QObject and derived classes inside a Qt container unless you store them as pointers, as copy of QObjects is disabled by design.
Furthermore, if you want to exploit polymorphic behavior you must use pointers, even if there is no explicit need to cast to derived classes in your code, as far as I can see. If you really need to resort to casting in some place, you could consider making your ToJson a template function.
There is a solution, but use caution as it is only reasonable/applicable in the following scenario:
Classes in question are primarily data storage classes
The classes in question would be entirely copy-able if they didn't inherit from QObject
Most importantly, the ONLY reason you have the class inherit from QObject is so that it can have meta properties.
If your code uses the class as a QObject for any reason other than to get meta information, you are almost certainly using it incorrectly if you are trying to store it by value (as explained by G. Giordano in their answer).
Misuse considerations aside, in order to JSON-ify a QVariant that stores a QObject subclass by value, you can use the QMetaType::create method and pass it the user type id and yourQVariant.constData().
Example:
MyQObject obj;
obj.db = 11.1;
QVariant value = QVariant::fromValue(obj);
std::string t = value.typeName();
int id = QMetaType::type(t.c_str());
void* v = QMetaType::create(id, value.constData());
obj_ptr = static_cast<QObject*>(v);
QJsonValue json = ToJson(obj_ptr); //json contains db = 11.1

Providing primitive casts in ActionScript 3

In languages like Java, C++ and etc there is the ability to provide, for example, a toInt() function to allow your code to be converted neatly by language features into a given primitive type. (In this example, an Int.)
That is, if you had myObject() with the standard casting function toInt() declared, then calls like Int(myObject) would just work. This is much more relevant to situations where you just want to forget about the cast altogether and just get something done - someVar:Int = myObject + 3 ... for an arbitrary example.
I've searched through AS3 docs and done some searching outside that but it appears there is no such sets of functions, interfaces, or other such things easily accessible in AS3. Does anyone know such a thing? It seems like essential knowledge in any language that supports such casting features and I'm at my wit's end with the verbosity of writing a partially qualified name like myObject.toInt() in the midst of mathematical work.
It's a common misconception that operator overloading in AS3 is impossible. It's not, but it's not entirely common practice, and it doesn't work as in other languages.
AS3 is "gradually typed". This means that you can specify type when you want to, you don't have to, and when performing operations on two different types it'll infer/cast for you in a logical way.
For objects, AS3 provides the valueOf():Object and toString():String functions which allow you to define the automatic handling of casting. The former provides the "primitive value of the object" while the latter defines the "String representation of the Object".
The default value for both is the String "[object ClassName]", but you can override this default. Here's an example:
package
{
import flash.display.Sprite;
import flash.utils.getQualifiedClassName;
public class Main extends Sprite
{
public function Main():void
{
trace("-----------------------------");
var foo = new MyClass();
trace("foo is: ");
trace(foo);
trace("foo+foo is:");
trace(foo+foo);
trace("foo+foo+'--' is:");
trace(foo+foo+"--");
trace("'--'+foo+foo is:");
trace("--"+foo+foo);
trace("Math.PI/foo:");
trace(Math.PI/foo);
trace("'5'+foo is:");
trace('5'+foo);
trace("false || foo is:");
trace((false || foo));
trace("foo | 0xC is:");
trace(foo | 0xC);
trace("typeof(foo) is:");
trace(typeof(foo));
trace("getQualifiedClassName(foo) is:");
trace(getQualifiedClassName(foo));
}
}
}
class MyClass {
public function valueOf():Object { return 3; }
public function toString():String { return "three"; }
}
And the trace output is:
-----------------------------
foo is:
three
foo+foo is:
6
foo+foo+'--' is:
6--
'--'+foo+foo is:
--threethree
Math.PI/foo:
1.0471975511965976
'5'+foo is:
5three
false || foo is:
three
foo | 0xC is:
15
typeof(foo) is:
object
getQualifiedClassName(foo) is:
Main.as$30::MyClass
The Boolean interpretation is interesting, but any non-null Object (or String) is true, so actually it works out. Whether the runtime calls valueOf() or toString() appears to be dependent on the types of the other arguments to the operators.

List of OO languages where object immutability can be compiler enforced

Can anyone give me a list of languages where class immutability can be compiler enforced and tested easily ?
I need to be able to do something like:
class immutable Person {
private String name = "Jhon"; // lets say the String is mutable
public Person(String name) {
this.name = name; // ok
}
public void setName(String newName) {
this.name = newName; // does not compile
}
public void getName() {
return this.name; //returns reference through which name can't be mutated
}
private void testImmutability() {
getName().setFirstChar('a'); // does not compile
}
}
EDIT:
For a little more clarification, see here.
Functional programming languages like OCAML, Haskell, and Erlang.
F# and Scala both have the ability to created compiler-enforced immutable types (i.e. classes).
The following shows the basics in F#...
// using records is the easiest approach (but there are others)
type Person = { Name:string; Age:int; }
let p = { Person.Name="Paul";Age=31; }
// the next line throws a compiler error
p.Name <- "Paulmichael"
Here's the equivalent Scala. Note that you can still make mutable objects by using var instead of val.
class Person(val name: String, val age: Int)
val p = new Person("Paul", 31)
// the next line throws a compiler error
p.name = "Paulmichael"
Joe-E
From the language spec
3.4 Immutable Types
A type T is immutable if and only if it implements
the marker interface org.joe_e.Immutable according to the overlay
type system. The (empty) org.joe_e.Immutable interface must be provided
by the Joe-E implementation. The
intuition behind an immutable object
is that such an object cannot be
changed (mutated) in any observable
way, nor can any objects reachable by
following the elds of the immutable
object. The contents of an immutable
objects' elds and any objects
reachable from an immutable object
must not change once the object is
constructed. With the exception of
library classes explicitly deemed to
implement Immutable, an immutable
class must satisfy additional
linguistic restrictions enforced by
the verier (x4.4) to ensure this
property. Library classes that cannot
be automatically verified and are
deemed immutable must be carefully
manually veried to expose no
possibility for modication of their
contents. Note that immutability does
not place any restrictions on any
local variables dened within the
immutable class. It also says nothing
about the mutability of the arguments
passed to methods. It only applies to
the values stored in and objects
reachable from the immutable class's
elds
It also introduces useful notions of powerless, and selfless types.
The D (version D2) programming language has immutability. It has OOP, but immutability is rather a concept from functional pl. There it's called purity.

Why is it not possible to declare a function with VAR return type?

In C#, we have var data type but we can't use it as functions return type.
Why this is not possible?
public var myFunction()
{
var = some operations
}
I believe it's partly due to the design of the compiler. Eric Lippert blogged about why fields can't use implicit typing, and I suspect some of the same arguments hold for methods.
But you could easily end up with ambiguity anyway. For example:
var Method1(bool callMethod2)
{
return callMethod2 ? Method2() : null;
}
var Method2()
{
return Method1(false);
}
What should the type be here?
A simpler example:
var Method1(bool throwException)
{
if (!throwException)
{
return Method1(true);
}
throw new Exception("Bang!");
}
Admittedly this sort of ambiguity could simply be disallowed, but I suspect that the design team felt that the added complexity of both design and implementation wasn't worth the benefit. Don't forget that they're running with limited resources - given a choice between var for methods and async/await, I'd pick the latter in a heartbeat. (Admittedly there are other features I'd have picked instead of dynamic, but that's a different matter...)
Note that return type inference is performed for lambda expressions, so the very idea of it isn't crazy. For example:
IEnumerable<string> x = new[] { "x", "y", "z" };
var result = x.Select(s => { return s.Length; }); // Long form
There the compiler infers the complete type of the lambda expression when it performs overload resolution on Select, converting it to a Func<string, int>. It's not inconceivable to apply the same ideas to methods - just complicated.
var is NOT a datatype in C#. That's why you cannot use it as a return parameter. The compiler infers the type at compile time from the right handside of the assignment and bearing in mind that it is known at compile time you need to use the real type as return value. In C# 4.0 you could use the dynamic type:
public dynamic myFunction()
{
var = some operations
}

how to make a map<CLSID, string>?

I want to create a container which can associate a CLSID structure to something else (for example, a string); for example, std::map.
(the CLSID means standard Windows CLSID structure)
However when I want to use its find() and insert (object[clsid] = string), the STL just failed and gives errors.
Does anyone know how to solve this?
For example:
typedef std::map<CLSID, std::string> MyCLSIDMap;
MyCLSIDMap mymap;
CLSID sample = CLSID_NULL;
mymap[sample] = string("test"); // compilation failed here
As Alex has answered, std::map needs to compare it's keys with op<.
bool operator<(CLSID const& l, CLSID const& r)
{
return memcmp(&l, &r, sizeof(CLSID)) < 0;
}
Does your CLSID structure support a usable operator<()? That's crucial for std::map (you can build it as a separate bool functor taking two const CLSID& arguments, it doesn't have to be a method operator<() in CLSID -- but then you'll have to say std::map and not just map ...!).
To use an STL map where the keys are structures, you'll need to provide your own strict weak ordering function object:
struct CompareCLSID
{
bool operator()(const CLSID &s1, const CLSID &s2) const
{
// returns true if s1 is less than s2
}
};
and then your map's type would be map<CLSID, string, CompareCLSID>.
However, if you don't need your container is sorted (that's my guess), you should be using hash<> or hash_map<>. In that case, you'll have to provide your own hash function.