I need to create a DIVariable from an existing MDNode.
According to the documentation, DIVariable inherits from MDNode. But directly attempting to create gives the error:
error: no matching constructor for initialization of 'llvm::DIVariable'
DIVariable newDIVar(*newMDNode);
^ ~~~~~~~~~~
/root/llvm-7.0.0/include/llvm/IR/DebugInfoMetadata.h:2193:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'llvm::MDNode' to 'const llvm::DIVariable' for 1st
argument
class DIVariable : public DINode {
I tried going one level further and creating a DINode from the MDNode to see if that works, which gives a similar error:
error: no matching constructor for initialization of 'llvm::DINode'
DINode newDINode(*newMDNode);
^ ~~~~~~~~~~
/root/llvm-7.0.0/include/llvm/IR/DebugInfoMetadata.h:155:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'llvm::MDNode' to 'const llvm::DINode' for 1st
argument
class DINode : public MDNode {
That error doesnt make sense to me. How does a class that inherits from another not convert to it implicitly?
Found an answer for anyone searching in the future.
In r234255 many implicit copy constructors were removed in favor of cast<>, isa<>, and dyn_cast<>.
Related
Help me solve this puzzle: In the following code I have an std::variant which forward declares a struct proxy which derives from this variant. This struct is only used because recursive using declarations are afaik not a thing in C++ (unfortunately). Anyway, I pull in all the base class constructors of the variant which define for each declared variant alternative T
template< class T >
constexpr variant( T&& t ) noexcept(/* see below */);
according to cppreference. I would assume that this means that a constructor for std::initializer_list<struct proxy> as type T is also defined. However, this doesn't seem to be the case. The following code results in an error:
#include <variant>
using val = std::variant<std::monostate, int, double, std::initializer_list<struct proxy>>;
struct proxy : val
{
using val::variant;
};
int main()
{
proxy some_obj = {1,2,3,2.5,{1,2}};
}
CompilerExplorer
Clang Error (because gcc doesn't go into much detail):
<source>:12:11: error: no matching constructor for initialization of 'proxy'
proxy some_obj = {1,2,3,2.5,{1,2}};
^ ~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/13.0.0/../../../../include/c++/13.0.0/variant:1434:2: note: candidate template ignored: could not match 'in_place_type_t<_Tp>' against 'int'
variant(in_place_type_t<_Tp>, initializer_list<_Up> __il,
^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/13.0.0/../../../../include/c++/13.0.0/variant:1455:2: note: candidate template ignored: could not match 'in_place_index_t<_Np>' against 'int'
variant(in_place_index_t<_Np>, initializer_list<_Up> __il,
^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/13.0.0/../../../../include/c++/13.0.0/variant:1424:2: note: candidate template ignored: could not match 'in_place_type_t<_Tp>' against 'int'
variant(in_place_type_t<_Tp>, _Args&&... __args)
^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/13.0.0/../../../../include/c++/13.0.0/variant:1444:2: note: candidate template ignored: could not match 'in_place_index_t<_Np>' against 'int'
variant(in_place_index_t<_Np>, _Args&&... __args)
^
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/13.0.0/../../../../include/c++/13.0.0/variant:1401:7: note: candidate inherited constructor not viable: requires single argument '__rhs', but 5 arguments were provided
variant(const variant& __rhs) = default;
What I get from this is that the above mentioned constructor taking the variant alternatives T is not considered. Why?
Your proxy class does not have a declared constructor that accepts a std::initializer_list<proxy>. What it has, is a constructor template that accepts any type, T. But for that template to be chosen, the compiler has to deduce the type of T. The braced-init-list {1,2,3,2.5,{1,2}} does not have any inherent type though, so the compiler can't deduce the type T.
It's easy to think that a braced-init-list is a std::initializer_list, but that is not the case. There are some special cases where a std::initializer_list will be implicitly constructed from a braced-init-list, but deducing a template type parameter is not one of those cases.
You could explicitly construct a std::initializer_list<proxy>, i.e.
proxy some_obj = std::initializer_list<proxy>{1,2,3,2.5,std::initializer_list<proxy>{1,2}};
But keep in mind that std::initializer_list only holds pointers to its elements, and it does not extend their lifetimes. All of those proxy objects will go out of scope at the end of the full expression, and some_obj will immediately be holding a std::initializer_list full of dangling pointers. If you need a recursive type, you will almost certainly need to dynamically allocate the recursive children (and remember to clean them up, as well). std::initializer_list is not sufficient for this use case.
I have the struct student and I did not declare a constructor. What will happen if I do the following?
struct student{
int assns, mt, finalExam;
float grade(){…}
}
student billy (60, 70, 80);
This answer is written according to the question heading, and not the body, as they seem to be gravely conflicting, hope the OP edits this.
You will encounter a error during compile time.
Code:
#include <iostream>
class test
{
int tt;
};
int main ()
{
test t1 (34);
}
Compiler Error:
In function 'int main()':
10:17: error: no matching function for call to 'test::test(int)' 10:17: note: candidates are:
2:7: note: test::test()
2:7: note: candidate expects 0 arguments, 1 provided
2:7: note: constexpr test::test(const test&)
2:7: note: no known conversion for argument 1 from 'int' to 'const test&'
2:7: note: constexpr test::test(test&&)
2:7: note: no known conversion for argument 1 from 'int' to 'test&&'
This happens as there is no constructor defined which takes a parameter. Without the ctor there is no meaning of class, as you can never initialize its data member, and how can you expect something to be constructed if the construction company itself is absent.
The compiler will throw error.
I'm trying to understand the meaning of the errors that we generally face in out C++ programs.
While compiling a program I got a error (I did this error intentionally, please don't tell that how to correct that) and there a note is present which is :
note: no known conversion for argument 1 from ‘int’ to ‘const account&’
I want to understand the meaning of this note.
My program is :
#include<iostream>
class account
{
private:
int a_no;
public:
account()
{
a_no = 0;
}
void showData()
{
std::cout<<"\n account number = "<<a_no<<std::endl;
}
};
int main()
{
account a1;
a1.showData();
account a2(2);
a2.showData();
return 0;
}
I know that I haven't defined a constructor which can take one argument and doing that will remove my error.
Okay, while compiling this I got:
file1.cpp: In function ‘int main()’:
file1.cpp:20:17: error: no matching function for call to ‘account::account(int)’
account a2(2);
^
file1.cpp:20:17: note: candidates are:
file1.cpp:7:9: note: account::account()
account()
^
file1.cpp:7:9: note: candidate expects 0 arguments, 1 provided
file1.cpp:2:7: note: account::account(const account&)
class account
^
file1.cpp:2:7: note: no known conversion for argument 1 from ‘int’ to ‘const account&’
I want to know what is meaning of last line file1.cpp:2:7: note: no known conversion for argument 1 from ‘int’ to ‘const account&’ ?
1) You already know that you don't have an constructor that takes an int.
2) You know that you are trying to construct account with an int.
3) If you don't do it, compilers will create default copy-constructors, assignment-operators
4) The default copy-constructor takes a const reference to account
So what happens here? As there is only a default-constructor and you are constructing with one parameter the compiler thinks you want to copy-construct. As you are giving him an int as parameter for the copy-constructor, the compiler tries to convert the int to an account - which doesn't work, and he tells you about it: "no conversion possible from int to account"
This is very important to know as this is a source of many bugs. You propably didn't want to call the copy-constructor. But what happens if the compiler really finds a way to convert the type you used as a parameter to account? A mess....
I want to know what is meaning of last line file1.cpp:2:7: note: no known conversion for argument 1 from ‘int’ to ‘const account&’ ?
First, the message tell you
no matching function for call to ‘account::account(int)’
And there're two candidates, the 1st is the default ctor, but
file1.cpp:7:9: note: candidate expects 0 arguments, 1 provided
The 2nd is the copy ctor (implicitly generated), and its parameter's type is const account&, but
file1.cpp:2:7: note: no known conversion for argument 1 from ‘int’ to ‘const account&’
class constructor is a simple function as like as others, so when you send a int type to the function as parameter, you need to define parameter type for function :
class account
{
private:
int a_no;
public:
account(int a){ a_no = a; }
};
now, when you type account a2(2); int type defined for constructor and there isn't any problem
today I found that boost::hana's map and set aren't default constructable, while the tuple is. Is there any particular reason for this because it is quite annoying.
This
#include <boost/hana/set.hpp>
// ^^^ or map
constexpr boost::hana::set<> a{};
// ^^^ or map
int main(){}
fails with the following error:
main.cpp:3:30: error: no matching constructor for initialization of 'const boost::hana::set<>'
constexpr boost::hana::set<> a{};
^~~
/home/russellg/Documents/boost/hana-0.6.0/include/boost/hana/set.hpp:65:28: note: candidate constructor not viable: requires single argument 'xs', but no arguments were provided
explicit constexpr set(tuple<Xs...> const& xs)
^
/home/russellg/Documents/boost/hana-0.6.0/include/boost/hana/set.hpp:69:28: note: candidate constructor not viable: requires single argument 'xs', but no arguments were provided
explicit constexpr set(tuple<Xs...>&& xs)
^
/home/russellg/Documents/boost/hana-0.6.0/include/boost/hana/set.hpp:57:12: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were
provided
struct set
^
/home/russellg/Documents/boost/hana-0.6.0/include/boost/hana/set.hpp:57:12: note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 0 were
provided
1 error generated.
even though it is perfectly valid to have an empty map or set:
#include <boost/hana/set.hpp>
// ^^^ or map
constexpr auto a = boost::hana::make_set();
// ^^^ or map
int main(){}
Which compiles flawlessly.
Any help is appreciated.
EDIT:
It doesn't actually matter if it is empty, it is always illegal to default construct maps and sets.
The hana::set and hana::map representations are implementation-defined. The documentation warns against their direct usage and mentions that the canonical way to create these is via hana::make_set and hana::make_map respectively. The documentation states:
The actual representation of a hana::set is implementation-defined. In particular, one should not take for granted the order of the template parameters and the presence of any constructor or assignment operator. The canonical way of creating a hana::set is through hana::make_set.
hana::tuple is a simpler container, documents its representation, and strives to maintain some parity with std::tuple. The hana::basic_tuple documentation notes:
[...] hana::tuple aims to provide an interface somewhat close to a std::tuple [...]
As to why hana::set and hana::map's representations are implementation-defined, consider reading the FAQ, but in short:
allows more flexibility to implement compile-time and runtime optimizations
knowing the type is usually not very useful
There is a github issue to consider adding a default-constructor for hana::map.
I have a class, MyClass, with an overloaded [] operator that takes an anonymous enum of type MyEnum. I can use it fine in code, but cannot inspect the object using lldb. When I try , I get the following error . .
(lldb) p myObject[MyEnum::value]
error: no viable overloaded operator[] for type 'MyClass'
note: candidate function not viable: no known conversion from 'int' to 'MyEnum' (aka '<anonymous enum>') for 1st argument
Can anyone explain why the debugger will not convert the enum properly?
[xcode 5.1.1]
It appears you need to cast the enumeration:
p myObject[(MyEnum)MyEnum::value]
^^^^^^^^