Error using anonymous enums as function arguments in lldb - c++

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]
^^^^^^^^

Related

LLVM MDNode inheritence

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<>.

Why do char{} and char() work as a temporary variable for a char* argument?

In Visual C++ 2017 (with /std:c++14 or with /std:c++17), the following code works:
void TakePtr(char*); // const or not
int main()
{
TakePtr(char{});
TakePtr(char());
}
I don't understand why it works.
Apparently, the following would also work (as expected):
void TakeChar(char);
TakeChar(char{});
TakeChar(char());
How does the compiler deduce (or convert) the type char to char*, when char{} or char() is used as an argument?
Now, if I have both char and char* overloads, it works without any error/warning about ambiguity:
void TakePtr(char*);
void TakePtr(char);
TakePtr(char{}); // Chooses 'char'
TakePtr(char()); // Chooses 'char'
Why is the compiler okay with char{} for TakePtr(char*)?
And why doesn't it give a warning/error when choosing the better version? Such behavior is bound to break existing code.
For sure, the compiler isn't happy with:
void TakePtr(char*);
char c{};
TakePtr(c);
Because Visual lies a lot. Especially older one. Your code prompts clang to report an error:
<source>:9:6: error: no matching function for call to 'TakePtr'
TakePtr(char{});
^~~~~~~
<source>:5:6: note: candidate function not viable: no known conversion from 'char' to 'char *' for 1st argument
void TakePtr(char*); // const or not
^
<source>:10:6: error: no matching function for call to 'TakePtr'
TakePtr(char());
^~~~~~~
<source>:5:6: note: candidate function not viable: no known conversion from 'char' to 'char *' for 1st argument
void TakePtr(char*); // const or not
^
2 errors generated.
Visual is known to be "wonky" in term of following C++ standard, so don't rely on it too much. Try to verify with clang / gcc, just to be sure.
This is simply MSVC being behind: the rule in C++03 was that any constant expression of integer type and value 0 was a null pointer constant and could thus be converted to char*. Certainly char() qualifies—and char{} means the same thing, although it never overlapped with the rule.

How to find by a key of type std::wstring_view in std::unordered_map<std::wstring, T>?

I have
std::unordered_map<std::wstring, std::vector<unsigned>> map;
when I try
map.find("asdf"sv)
I get
error C2664: 'std::_List_const_iterator<std::_List_val<std::_List_simple_types<_Ty>>> std::_Hash<std::_Umap_traits<_Kty,std::vector<unsigned int,std::allocator<unsigned int>>,std::_Uhash_compare<_Kty,_Hasher,_Keyeq>,_Alloc,false>>::find(const std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>> &) const': cannot convert argument 1 from 'std::wstring_view' to 'const std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>> &'
is it possible to make map.find() compile with std::wstring_view or at least to do the search without constructing std::wstring?
What you are trying to do is called "heterogeneous lookup" (basically, the type of the map and the type you're trying to use to lookup are different types). In C++20, thanks to P0919, we are going to get new overloads of unordered_map::find() that will allow what you're trying to do to work.
Until then, the only relevant overload takes, specifically, a Key const&. And basic_string's constructor from basic_string_view is explicit (see #10). So in C++17, you have to write:
map.find("asdf"s)
or
map.find(std::string("asdf"sv));

Conversion operator doesn't work with sleep_until

I try to use a custom class with a conversion operator in a call to std::this_thread::sleep_until. Here's the code that I use:
class A
{
public:
...
operator std::chrono::time_point<std::chrono::system_clock>() const {
return std::chrono::time_point<std::chrono::system_clock>{} +
std::chrono::duration_cast<std::chrono::system_clock::duration>(timestamp_); }
private:
std::chrono::nanoseconds timestamp_;
};
A a;
std::this_thread::sleep_until(a); // This doesn't compile (note the overload with time_point).
std::this_thread::sleep_until((std::chrono::time_point<std::chrono::system_clock>)a); // But this does.
The compiler error is error C2664: 'void std::this_thread::sleep_until(const xtime *)': cannot convert argument 1 from 'A' to 'const xtime *'.
Could anybody give me a hint what I'm doing wrong here and how it should be done correctly?
std::this_thread::sleep_until is a function template. During template argument deduction, conversion won't be considered.
Conversion happens after deduction is done. Thus your conversion operator has no effect if you don't invoke it explicitly.

error: use of overloaded operator '*' is ambiguous

When I try to compile this source in c++:
void ParticleSystem::setState(std::vector<Vec2f>& statesVector)
{
std::vector<Vec2f> pState(2);
for (int i = 0; i < 2*np; i += 2) {
pState[0] = *statesVector[i];
pState[1] = *(statesVector[i+1]);
(*particles[i/2]).setState(pState);
}
}
I get the following error:
ParticleSystem.cpp:110:15: error: use of overloaded operator '*' is ambiguous (operand type
'value_type' (aka 'gfx::TVec2<float>'))
pState[0] = *statesVector[i];
^~~~~~~~~~~~~~~~
ParticleSystem.cpp:110:15: note: built-in candidate operator*(float *)
ParticleSystem.cpp:110:15: note: built-in candidate operator*(const float *)
ParticleSystem.cpp:111:15: error: use of overloaded operator '*' is ambiguous (operand type
'value_type' (aka 'gfx::TVec2<float>'))
pState[1] = *(statesVector[i+1]);
I have look for the error already in the forums and followed some steps but i never get to make it work. Moreover, I've also tried to understand the explanation in the notes of the error, but I cannot.
I really hope someone can help me.
Finally, if someone rates this question negatively, at least explain why, please.
The problem is that you didn't understand the syntax that comes with references. While you do declare a reference with &, you use it as you would use the actual variable and not like a pointer, which means you can't use the operator * on it (unless it's a reference on a pointer type). Using the * operator produces the same effects as if you were to use it on a regular variable.
You can fix your problem by removing the * in your code like this:
pState[0] = statesVector[i];
pState[1] = statesVector[i+1];
particles[i/2].setState(pState);
Your code could compile as is if you defined operator* in the Vec2f class and made it return a Vec2f. However, this make little sense in a semantics point of view (a dereferenced value should not give something of the same type) so this is not the way to fix your problem.