cannot implicitly convert expression e of type main.T to main.main.T - d

What does the double main mean? Are there two nested levels of main scope somehow?
Error: cannot implicitly convert expression myFunction(f) of type main.M!(Tuple!(wstring, wstring)*) to main.main.M!(Tuple!(wstring, wstring)*)
The only difference is main.main instead of main.
Error: cannot implicitly convert expression myFunction(f) of type
main.M!(Tuple!(wstring, wstring)*)
to
main.main.M!(Tuple!(wstring, wstring)*)
Context:
M is a struct defined at the top level
the call to myFunction(f) is inside a delegate literal that is immediately called; something like (delegate bool () {myFunction(f);return true;})()

Turns out I had two copies of the struct definition.
M struct definition
definition of myFunction which returns values of type M
M struct definition, again
M = myFunction(f);
thus we have a type mismatch, since the two M's are actually different types, but under the same name

Related

Function style casting using the `new T()` operator in C++

Here is an example of a simple function style casting done by int(a):
float a = 5.0;
int b = int(a);
More info from cpprefrenece:
The functional cast expression consists of a simple type specifier or a typedef specifier followed by a single expression in parentheses.
I have 2 questions:
1) would using the new operator still count as a functional cast?
int* b = new int(a);
2) Assuming test is a class, then test t = test(1); is a function style casting to test but test t = test(1, 2); isn't because it has more than 1 expression in parenthesis?
would using the new operator still count as a functional cast?
No, the use of the new operator(like you used in your example) is not a use case of functional cast.
test t = test(1, 2); isn't because it has more than 1 expression in parenthesis?
Both test t = test(1); and test t = test(1,2); are copy initializations. Now, the subexpression test(1) is indeed a functional cast where the appropriate test constructor will be used. While the subexpression test(1, 2) is not as it has more than a single expression inside parenthesis.
1) New expression
A new-expression is a special case of... a new-expression. Nothing less, nothing more. It results in creation of object of given type in dynamic storage and , for class-types, in a call to constructor with given argument list. For trivial types new-expression provides an initializer.
A new-expression isn't a cast, albeit initializing parameters from argument list given in parenthesis may involve implicit casts. If returned result of new-expression wasn't used, the created object would continue to exist. And unless there is a curious contingency involved, it would not be correctly freed.
A functional cast would produce an xvalue, an object which would expire at end of enclosing expression.
C++ parser by design is a "greedy" parser. It doesn't try to single out every token first, it's a complex algorithm to match statements to whole patterns, as longer as possible, appropriate for current context (and context may change in result). The "greedy" nature becomes obvious in case of some ill-formed or ambiguous code. As a rule, if something can be parsed wrong, it will be parsed wrong, but not until whole statement would be analyzed.
Speaking of functional cast, typename(name) syntax may appear in declarations of variables or types, which result in following being a legal declaration:
int foo ( int (a) )
{
return a;
}
It's because since times of C we can declare some eldritch array of pointers as void (*(*f[])())(), which declares f as array of pointers to function returning a pointer to function returning void.
In result, initializing a variable with a functional cast may create an ambiguous code:
float fvar = 1.0f;
double dvar ( int(fvar) );
It declares a double(int) function named dvar! You wouldn't spot it, until you try assign to it:
auto v = dvar; // v is a pointer to function.
dvar = 4; // error
The declaration of dvar as whole matches BOTH a function declaration and a variable declaration. In this case compiler MUST choose wrongly, but diagnostics are optional. It's exacerbated by fact that C and C++ are allowing variable identifiers to match type names.
2) Initialization of object
Yes, the expression test(1) is a functional cast even if test is a class. By definition it results in considering an existing constructor to be called.
class test {
public:
test(int arg): b(arg) {}
protected:
int b;
};
Here constructor test(int) is called a conversion constructor as it can take exactly one parameter and its usage permits use of type-id test in functional cast - from int or int-compatible type. Constructors with more than one parameter without default value do not bear this name. For class test , te expression test(1,2) is ill-formed.
In fact, unless such constructor qualified as explicit, it would allow an implicit conversion:
struct test {
test(int a) {std::cout << "int " << a << std::endl;}
explicit test (float a) {std::cout << "float " << a << std::endl;}
};
int main()
{
test b = 1; // calls (int) constructor
test c = 2.0f; // calls (int) constructor
test d = test(3.0f); // function cast calls (float) constructor
}
P.S. C++11 allowed to escape functional cast syntax for initialization of class-type object. For above class it would be test{1}. But it also can be an aggregate initialization, if test would be trivial:
struct test {
int b;
};
test t = test{1};
New Operator
Yes. From the cppreference page on the new keyword
The object created by a new-expression is initialized according to the following rules:
For non-array type, ...
If initializer is a parenthesized list of arguments, the object is direct-initialized.
And if we check out the page on direct initialization, we find that syntax (3) on that page is
T ( other )
T ( arg1, arg2, ... )
initialization ... by functional cast or with a parenthesized expression list
So new is defined to perform direct initialization, and direct initialization is defined to perform a functional cast when necessary. There's more going on with regard to allocation in the background, but at some point down the line a functional cast may get performed.
More than 1 Expression
In regards to your second question, a "cast" is a conversion from one type to another. An initialization with one argument can be viewed as a cast, from the argument type T to the result type S. It makes no sense to think of test(1, 2) as a conversion from anything, since it takes two arguments and produces one value.

I do not understand why this compiles

I'm certainly missing something, but I do not understand why this compiles (with both g++ & clang++):
struct A
{
};
struct B
{
};
int main()
{
A a(B);
}
First of all, B is a type... not a value. How should I interpret this code?
It's interpreted as the declaration of a function named a, which takes one argument of type B and returns A.
It's simply a function declaration declaring a to be a function returning A and taking one unnamed parameter of type B.
It is valid because function declarations as opposed to function definitions are allowed within function definitions.
This issue is known as the most vexing parse. The line A a(B); can be interpreted as the declaration of a function named a returning an object of type A and taking an unnamed parameter of type B.
One way to avoid this issue is to use the uniform initialization syntax which was introduced in C++11, which consists in using braces instead of parenthesis: A a{B}; returns an error. The line is now interpreted as a variable declaration initialized with B, which is a type instead of a value.
Here's more information:
The Most Vexing Parse: How to Spot It and Fix It Quickly

About Function Pointer in C++

Do these lines mean the same? Both works without any warning messages!
int (*pFunc)() = func1; // I learned this is right.
int (*pFunc)() = &func1; // Works well with an ampersand too.
Why do I have to put an ampersand in this case? Without it, doesn't work!
int (CMyClass::*pMemberFunc)() = &CMyClass::memberFunc1;
Why do I have to specify namespace for functions in Classes even if the type of the function pointer matches exactly?
int (*pMemberFunc)() = CMyClass::memberFunc1; // Compiler error
int (*pMemberFunc)() = &CMyClass::memberFunc1; // Compiler error
Why can't I specify namespace in this case?
namespace myNamespace {
int func1() {}
}
int (myNamespace::*pFunc)() = myNamespace::func1; // Compiler error
int (myNamespace::*pFunc)() = &myNamespace::func1; // Compiler error
int (*pFunc)() = &myNamespace::func1; // Works!
Your first question, legalese of the Standard:
A pointer to member is only formed when an explicit & is used and its operand is a qualified-id not enclosed
in parentheses. [Note: that is, the expression &(qualified-id), where the qualified-id is enclosed in
parentheses, does not form an expression of type “pointer to member.” Neither does qualified-id, because
there is no implicit conversion from a qualified-id for a non-static member function to the type “pointer to
member function” as there is from an lvalue of function type to the type “pointer to function” (4.3). Nor is
&unqualified-id a pointer to member, even within the scope of the unqualified-id’s class. —end note ]
While it seems inconsistent at first, I do like the fact that it makes the semantics for pointers to members (be them functions or not) equivalent. This certainly has benefits when dealing with templates and decltype.
For the second question, you scope the pointer variable with CMyClass because yours is not a simple "() -> int" function: memberFunc1() is implicitly passed a CmyClass* argument you normally refer to as "this".
If you could truly pass nothing, you'd be missing information (and possibly crash) for the method to do its job correctly. If you're accustomed to "delegates" in other languages, do remember these can optionally store a "Target" pointer to the "this" object if the method is not static/global.
As for the third, it's a free standing function, so it's truly () -> int, but you're attempting to scope your pointer to the namespace, when in fact you're not declaring your variable inside the namespace block.
While the namespace certainly alters how symbols are searched for, it doesn't affect the convention call of the function at all.
1) about Q1, looking at the following code, as the func1 is a right-value of the function, so with or without "&" doesn't change the actual function address.
Look at the following code:
#include <stdio.h>
void foo(){
printf("foo called\n");
}
int main(){
printf("%p\n", foo);
printf("%p\n", &foo);
void (*FUNC) ();
FUNC = foo;
FUNC();
printf("address %p\n", FUNC);
printf("address %p\n", &FUNC);
return 0;
}
output is
0x101406eb0
0x101406eb0
foo called
address 0x101406eb0
address 0x7fff5e7f9a80
Q2 & Q3 )
Pointers to Member Functions Are Not Pointers
You can refer it here
https://www.safaribooksonline.com/library/view/c-common-knowledge/0321321928/ch16.html

What is the difference between &foo::function and foo::function?

I am using the gtkmm library on linux to draw a simple menu for my GUI.
In the below code the compiler complained about unable to resolve address
sigc::mem_fun(*this, AppWindow::hide)));
^
appwindow.cpp:15:41: note: could not resolve address from overloaded function
But when I insert the & it compiles fine
m_menu_app.items().push_back(MenuElem("Quit",
sigc::mem_fun(*this, &AppWindow::hide)));
What difference does it make here? Isn't the hide function just an address in the first place?
This is the exact definition of the function-to-pointer conversion, [conv.func]:
An lvalue of function type T can be converted to a prvalue of type
“pointer to T.” The result is a pointer to the function.55
55) This conversion never applies to non-static member functions because an lvalue that refers to a non-static member function
cannot be obtained.
Thus the decay that we see with normal, non-member functions1 doesn't apply and you need to explicitly take the address.
I.e.
void f();
struct A {
void f();
static void g();
};
auto a = f; // Ok: auto deduced as void(*)()
auto b = A::f; // Error: A::f not an lvalue, auto cannot be deduced
auto c = A::g; // Ok: auto deduced as void(*)()
1 Or static member functions.
For global (non-member) functions, the name of the function evaluates to the address of that function except when passed to the & operator, so you can (for example) assign to a pointer to a function either with or without the & equivalently:
int f() {}
int (*pf1)() = f;
int (*pf2)() = &f;
So, in this case there's really no difference between the two.
For member functions1, however, the rules are a bit different. In this case, the & is required; if you attempt to omit the &, the code simply won't compile (assuming a properly functioning compiler, anyway).
There's no particular reason this would have to be the case--it's just how Bjarne decided things should be. If he'd decided he wanted the name of a member function to evaluate to a pointer to a member (equivalent to how things work for non-member functions) he could have done that.
1. Other than static member functions, which mostly act like non-member functions.
When a function is a non-static member function of a class, then it is necessary to use the form &ClassName::functionName when a pointer to the member function is expected in an expression.
When a function is a static member function of a class, both ClassName::functionName and &ClassName;:functionName can be used when a pointer to a function is expected in an expression.
When a function is a global, i.e. non-member, function, both functionName and &functionName can be used when a pointer to a function is expected in an expression.

How to declare a pointer to a template function in D lang?

I'm playing with some D code.
I have some functions filtering on a array:
auto Case1Filters(R)(R lines) if(isInputRange!R) { ... }
auto Case2Filters(R)(R lines) if(isInputRange!R) { ... }
I want to have a function pointer and assign to it one of my filters, so I declared a variable like this:
auto function(R)(R lines) filter = null;
And I get these error when compiling:
conv.d(54): Error: basic type expected, not function
conv.d(54): Error: function declaration without return type. (Note that constructors are always named 'this')
conv.d(54): Error: no identifier for declarator int function(R)(R lines)
conv.d(54): Error: semicolon expected following function declaration
It looks like the compiler thinks that I'm declaring a function.
I tried with an alias, too, but to no avail: is there a way to do this?
You can't have any type of dynamic dispatch to a template, for the same reason you can't have a virtual template function.
Despite all appearances D is a statically typed language which means that all function pointer declarations must have all types available (including the return type auto can only be used when the body is included).
So if R is already declared then you can do:
auto foo(R)(){//R is defined here as some type
Ret function(R lines) filter = null;//no template param when declaring the function pointer and concrete return type
filter = &Case1Filters!R;
filter(r);
}