How to solve ambiguous template overload of clear on local array? - d

Currently, I try to get the latest version of facebook's flint to get compiled.
The code fails with the D compiler version 2.081.1 on a similar construct as
import std.stdio;
void main()
{
long[] foo = [];
foo.clear();
}
Here is the short link to the example: https://run.dlang.io/is/ZSsPNS
with the messages:
onlineapp.d(5): Error: template object.clear cannot deduce function
from argument types !()(long[]), candidates are:
/dlang/dmd/linux/bin64/../../src/druntime/import/object.d(2855):
object.clear(T : Value[Key], Value, Key)(T aa)
/dlang/dmd/linux/bin64/../../src/druntime/import/object.d(2860):
object.clear(T : Value[Key], Value, Key)(T* aa)
How can this ambiguity be solved?
Any help is very much appreciated!

There is no ambiguity there - clear is a function that operates on associative arrays, not dynamic arrays, which is what long[] is.
Now, that of course doesn't mean the code works. :p
The issue is clear was renamed to destroy in 2.066, and removed in 2.070. Then, in 2.071, the current function was introduced, which clears AAs of their contents.
So, in summary: replace clear with destroy, and things should work.

Related

Was it possible to get a pointer to member from an instance of an object?

I was porting some legacy code to VS 2015 when this compiler error halted the build:
error C3867: 'OptDlg::GetFullModel': non-standard syntax; use '&' to create a pointer to member
Going to the corresponding file and line, I saw this:
Manager mgr = GetDocument()->GetManager();
OptDlg dlg;
...
mgr->SetFullModel(dlg.GetFullModel);
if ( dlg.GetFullModel )
mgr->SetSymm(...
GetFullModeland SetFullModel are the getter/setter pair for a member variable in two different classes:
class Manager {
...
bool GetFullModel() { return m_bFullModel; }
void SetFullModel(bool bFlag) { m_bFullModel = bFlag; }
....
};
class OptDlg {
...
void GetFullModel() { return m_bFullModel; }
void SetFullModel(bool bValue) { m_bFullModel = bValue; if ( bValue ) m_bInside = 0;}
Yep, something's wrong. Was dlg.GetFullModel supposed to be a pointer to a member function? I thought those use the class name, not an instance. Not to mention what that would mean for execution semantics...
C++ is still relatively new to me, so I tried Google. It had a lot on function pointers, but they all looked different from what I had:
&OptDlg::GetFullModel // Standard-compliant
vs
OptDlg::GetFullModel // The "normal" way to mess up getting a pointer to member, it seems
vs
dlg.GetFullModel // ?
Is dlg.GetFullModel just another way of getting a pointer to member function? If not, what is the "standard C++ version", if there is one? Is this just another one of those VS 6 "extensions"?
&OptDlg::GetFullModel // Standard-compliant
If your parameter types were supposed to be taking member functions, that's what you'd use. But they take booleans. It looks like you're just missing parentheses on your function calls, and it should be:
mgr->SetFullModel(dlg.GetFullModel());
if (dlg.GetFullModel())
mgr->SetSymm(...
Probably someone was ignoring warnings (or didn't have them on) and hence a pointer value (being produced through whatever shady means) was always being interpreted as non-NULL, hence boolean true.
Is this just another one of those VS 6 "extensions"?
It would appear to be the case, although this comment is the only documented evidence I can find it was an intentional/advertised "feature". Don't see any formal announcement of it being added or taken out.
It strongly looks to me like someone mis-typed dlg.GetFullModel() (which would call the function), not that they were trying to get a member function pointer.
Presumably the legacy compiler let it slide, taking the address of the function without using & and converting the non-null function pointer to bool (with value true) to pass into the set function.

c++ attempting to reference deleted function

I have been playing around with std::unique_ptr and the std::for_each algorithm to learn them and I then received this error "attempting to reference a deleted function" when I am attempting to move some variables from one container (std::map) to another.
This code is currently executed in a member function. Foo is just a generic class.
std::for_each(m_list1.begin(), m_list1.end(),
[&](std::pair<std::size_t,std::unique_ptr<Foo>> data_pair)
{
m_list2[data_pair.first] = std::unique_ptr<Foo>(std::move(data_pair.second));
});
m_list1.clear();
I tried various things but the problems still persists. I then tried using range-based for instead and suddenly it works.
for (auto& data_pair : m_list1)
{
m_list2[data_pair.first] = std::unique_ptr<Foo>(std::move(data_pair.second));
}
m_list1.clear();
What I want to know is why the second code executed with no problem, while the first code produced the error.
If you need more specific information, Just ask. If there's bad practice in my coding style, please advice on how to make it better.
There are two errors in your for_each code. First, map::value_type is pair<const Key, Value>. Second, your lambda expression is taking the argument by value, which means it attempts to copy the unique_ptr, hence the error. To fix it, take the argument by reference.
[&](std::pair<const std::size_t, std::unique_ptr<Foo>>& data_pair)
// ^^^^^ ^^^
{
m_list2[data_pair.first] = std::unique_ptr<Foo>(std::move(data_pair.second));
}
A better option is to not mention those types explicitly, instead use decltype
[&](decltype(m_list1)::value_type& data_pair)
{
m_list2[data_pair.first] = std::unique_ptr<Foo>(std::move(data_pair.second));
}
Now, your range-based for worked because you were binding the elements of the map to a reference by using for(auto& data_pair : m_list1). You'd have run into the same error as before if you'd instead used for(auto data_pair : m_list1) because that'd have attempted to make a copy of the elements.

Anonymous Functions, "Parse Issue: Expected Expression"

I'm getting the titular error, but I can't for the life of me figure out how to resolve it. I've scoured the internet a fair bit, but for the most part I can't find anything that pertains directly to, or solves, the problem I'm having, and all the information I read about anonymous classes, seems to agree with the code I wrote.
The essence of what I'm trying to do is; I have a struct, and I want that struct to contain a function pointer. What I'm having trouble with is when I define an instance of the struct, I'm trying to create and pass an anonymous function to the struct. But it's giving me a compile error.
Anyways, here are the details of the actual problem, the error occurs on this line,
[&](int x) { this->moveLeft(); };
It says "Parse Issue: Expected expression" and points to the ']'
of the following code
Combatant::CharacterData Combatant::characters = {
/*Name */"SomeName",
/*Folder */"SomeFolder",
/*Offense */1.0f,
/*Defense */1.0f,
/*Combos */{
{KeyMemory(KeyMemory::MOVE_LEFT, KeyMemory::JUMP),
[&](int x) { this->moveLeft(); };
},
{KeyMemory(KeyMemory::MOVE_LEFT, KeyMemory::JUMP),
[&](int x) { this->moveLeft(); };
}
}
}
The CharacterData struct is defined by this code:
struct Combo {
KeyMemory controls;
void (*execute)(int);
};
struct CharacterData {
std::string name;
std::string folder;
float offense;
float defense;
Combo comboList[5];
};
Any help, would be much appreciated. ^_^
You might need to use a std::function<void(int)> to hold your lambda. (Particularly since you are using [&]).
Also, I'm not sure [&] actually makes sense in a global context. Maybe you should be passing in the object to call moveLeft on, and using []. Also, that change might let you use your simple function pointer instead of a std::function.
The problem turned out to be that Clang, which is the compiler used by Xcode/Apple doesn't yet support lambda functions. From what I read however the feature is coming in the future.

Syntax for std::binary_function usage

I'm a newbie at using the STL Algorithms and am currently stuck on a syntax error. My overall goal of this is to filter the source list like you would using Linq in c#. There may be other ways to do this in C++, but I need to understand how to use algorithms.
My user-defined function object to use as my function adapter is
struct is_Selected_Source : public std::binary_function<SOURCE_DATA *, SOURCE_TYPE, bool>
{
bool operator()(SOURCE_DATA * test, SOURCE_TYPE ref)const
{
if (ref == SOURCE_All)
return true;
return test->Value == ref;
}
};
And in my main program, I'm using as follows -
typedef std::list<SOURCE_DATA *> LIST;
LIST; *localList = new LIST;;
LIST* msg = GLOBAL_DATA->MessageList;
SOURCE_TYPE _filter_Msgs_Source = SOURCE_TYPE::SOURCE_All;
std::remove_copy(msg->begin(), msg->end(), localList->begin(),
std::bind1st(is_Selected_Source<SOURCE_DATA*, SOURCE_TYPE>(), _filter_Msgs_Source));
What I'm getting the following error in Rad Studio 2010. The error means "Your source file used a typedef symbol where a variable should appear in an expression. "
"E2108 Improper use of typedef 'is_Selected_Source'"
Edit -
After doing more experimentation in VS2010, which has better compiler diagnostics, I found the problem is that the definition of remove_copy only allows uniary functions. I change the function to uniary and got it to work.
(This is only relevant if you didn't accidentally omit some of your code from the question, and may not address the exact problem you're having)
You're using is_Selected_Source as a template even though you didn't define it as one. The last line in the 2nd code snippet should read std::bind1st(is_Selected_Source()...
Or perhaps you did want to use it as a template, in which case you need to add a template declaration to the struct.
template<typename SOURCE_DATA, typename SOURCE_TYPE>
struct is_Selected_Source : public std::binary_function<SOURCE_DATA *, SOURCE_TYPE, bool>
{
// ...
};
At a guess (though it's only a guess) the problem is that std::remove_copy expects a value, but you're supplying a predicate. To use a predicate, you want to use std::remove_copy_if (and then you'll want to heed #Cogwheel's answer).
I'd also note that:
LIST; *localList = new LIST;;
Looks wrong -- I'd guess you intended:
LIST *locallist = new LIST;
instead.

regarding encryption method

i am using encrypt function of cryptography api(fun declared as virtual)
//fun declaration
TBool EncryptL(const TDesC8 &aInput, TDes8 &aOutput);
//function calling
TBuf8<10> text;
TBuf8<10> cipher;
text.Copy(_L("Hello"));
iEncryptor.EncryptL(text,cipher); it shows error expression syntax error
//fun definition
TBool CRSAAlgo::EncryptL(const TDesC8 &aInput,TDes8 &aOutput)
{
if(iEncryptor)
{
TInt len = iEncryptor->MaxInputLength();
}
}
i want to know what is exact problem
The main issue here, the reason your compiler complains is that you are using iEncryptor as an object or a reference, while it probably is a C++ pointer.
To move to the next stage, try using:
iEncryptor->EncryptL(text,cipher);
As you did not post the exact error message you get from the compiler I have to guess.
I assume the problem is that the EncryptL function you show expects to get arguments of type TDesC8 and you pass a TBuf8<10> to it. Unless TDesC8 were a typedef to TBuf8<10> these are different and therefore for the compiler incompatible types.
Ypou are also using iEncryptor once as a pointer: iEncryptor->MaxInputLength(); and at the location where you see the error as an object: iEncryptor.EncryptL(text,cipher);. Only one form can be correct. As we don't have more code from you I don't know which, but given the fact that the latter has the error I suspect the latter.