I'm working on Linux gcc environment and I need to initilize function arguments that are classes with default values.
When I do that with temporary instance of the class it makes an error like this: "default argument for [function argument] has type [class name].
for example:
void foo(std::wstring& str = std::wstring())
error: default argument for 'std::wstring& str' has type 'std::wstring'
P.S. this code is compiled without any error or warning with VC++.
How can I initilize the default value?
This is supposed to not compile. You are trying to bind an rvalue to a non-const reference. Say std::wstring const & str and it should work.
You could just create a function overload:
void foo() {
std::wstring str;
foo(str);
}
but I really miss the point.
EDIT:
I mean, that function's purpose is almost certainly to modify an input string. If you provide an empty input string that you can't access later, why bother?
You cannot bind non-const references to rvalues. Passing by value would work:
void foo(std::wstring str = std::wstring())
Or passing by reference-to-const:
void foo(const std::wstring& str = std::wstring())
Related
I am having a constructor like this:
class class_foo{
std::string s_;
class_foo(std::string& s) : s_(s){};
}
I know I can do:
std::string s = "test";
cf = class_foo(s);
Is there a way to do:
cf = class_foo("test");
But is says: note: candidate constructor not viable: expects an l-value for 3rd argument
#eerorika was right. I can simply use a const like here:
link
I am having a constructor like this:
void class_foo(std::string& s) : s_(s){};
A constructor cannot have a return type (even void).
Is there a way to do:
cf = class_foo("test");
Not if you want to keep the argument as non-const reference. It is however unclear why you want it to be non-const reference. Perhaps it doesn't need to be a non-const reference? If you don't intend to modify the argument, then you should use a reference to const. Then your suggested construction would work.
I have a function which accepts a std::string&:
void f(std::string& s) { ... }
I have a const char* which should be the input parameter for that function. This works:
const char* s1 = "test";
std::string s2{s};
f(s2);
This doesn't:
const char* s1 = "test";
f({s1});
Why isn't this possible? The funny thing is that CLion IDE is not complaining, but the compiler is:
no known conversion for argument 1 from β<brace-enclosed initializer list>β to βstd::basic_string<char>&β
This has nothing to do with constructing std::string from char const*.
f expects a lvalue to a string, and by creating a temporary instance on the spot, you're providing an rvalue, which cannot be bound to a non-const lvalue reference. f(string{}) is just as invalid.
Your function receives a non const reference and you are passing a temporary object, which requires a copy or a const reference parameter. Two solutions, creating another function to receive the object as a rvalue reference and call the other overload within
void f(string&& s) { f(s); }
to allow temporary objects as parameter, or change your function definition to receive any object but as a constant reference
void f(const std::string& s) { ... }
One option is to change your function to take a string by value, not by reference. Then it will work. In any case, in C++11 sometimes it's preferable to pass by value, not by reference.
Let's say we have got a raw C-style string "test". We can declare a function like this:
void printText(std::string textToPrint){
std::cout << textToPrint << "\n";
}
and we may call it in a following manner:
printText("test");
And this should be perfectly fine, as argument is an object, not a reference, so temporary object like std::string("test") should be created in time of calling function `printText()'.
Now given that, I have a following template:
template <typename T>
T checkMe(Proxy<T> arg){
std::cout << arg() << std::endl;
return arg();
}
where Proxy class declaration is as follows:
template <typename T>
class Proxy{
public:
Proxy(std::function<T&()> caller);
Proxy(std::shared_ptr<T> dataPtr);
T& operator()();
private:
std::function<T&()> m_functional;
std::shared_ptr<T> m_data;
};
It's purpose is to make some of the functions be called with two object types:
One is shared_ptr to the data and another is functional object, that returns this type of data.
Now when I want to call function checkMe error happens, that I do not know why appears and how to solve it. One thing is:
getMe(std::make_shared<int>(255));
And this in my opinion should be perfectly fine, as Proxy's constructor takes shared_ptr as argument and creates itself based on it. But this gives compiler's deduction error. Whereas, when I call function like this:
getMe<int>(std::make_shared<int>(255));
Well now it's fine. I do not know why does compiler cannot deduce the type on it's own.
Second case is calling it with a functional object:
getMe<int>(std::bind(getNumberMult,5,6));
Where getNumberMult is defined as follows:
int xy;
int& getNumberMult(int x, int y){
return xy = x*y;
}
Here conversion error occurs. Could someone please specify is it possible and how to achieve desired behavior of the given code and explain what is wrong with my understanding of the mechanism? I would like to use this code as follows:
getMe(std::make_shared<int>(300));
getMe(std::bind(getNumberMult, 6, 7));
Compiler errors:
when using
getMe<int>(std::bind(getNumberMult, 5, 6));
path/to/file:36: error: C2664: 'T getMe<int>(DataProxy<T>)' : cannot convert argument 1 from 'std::_Bind<true,int &,int &(__cdecl *const )(int,int),int,int>' to 'DataProxy<int>'
with
[
T=int
]
With T checkMe(Proxy<T> arg), arg should be a Proxy<T> (or inherit from it).
Compiler doesn't check the infinite possibilities to test each Proxy<T> can be construct from given argument.
So generally I know now why it is so, and what should I do to fix it.
Consider following object:
struct Test{
Test(std::string someString){}
};
So we need std::string just for constructing object of this class.
We can do without std::string created explicitly in following manner:
int main(){
Test someVariable("someRawString");
}
It's gonna work and it is completely fine. What happens underhood is:
compiler meets instruction for creating object of Test class
It sees, that given argument is not of type required by Constructor
because of the fact, that required argument is a value, not a reference (const reference would also be fine) it creates temporary object of type std::string and passes this temporary object to the constructor
Object is successfully created.
Now let's consider function:
void someTestFunction(Test someTest){}
It requires object of type Test, that is constructed from std::string
Given that, it should be fine to invoke this function in following manner:
someTestFunction("someRawText");
But it's not fine. This gives us error of converting arguments. Reason for it is quite simple: C++ allows only one step of converting, when passing parameters to the function. So compiler can:
cast raw string to std::string
create Test object with std::string
But it cannot:
cast raw string to std::string
cast std::string to Test (too many conversions)
invoke function with Test
Exactly the same things happened with the given code. To make it work we should use:
getMe<int>(std::make_shared<int>(300));
getMe<int>(std::function<int&()>(std::bind(getNumberMult, 6, 7)));
Why is it so?
std::make_shared<int> has return type of std::shared_ptr<int>, so no conversion was required to invoke a function.
std::bind... has a returning type different than std::function, it has it's own implementation defined return type. That is why this second cast would be required here, which is not allowed by C++. When we cast it explicitly, then only one implicit cast is required and everything works fine.
This is a newbie question but I cannot understand how it works.
Suppose I have the function like the one below
void foo(const std::string& v) {
cout << v << endl;
}
And the call below in my program.
foo("hi!");
Essentially I am passing a const char* to a function argument that is const reference to a string so I have a doubt on this call.
In order to pass an argument by reference, am I right to say that the variable must exist at least for the duration of the call? If it is so, where is created the string that is passed to the function?
I can see that it works : does it happen because the compiler creates a temporary string that is passed to the argument or the function?
does it happen because the compiler creates a temporary string that is passed to the argument or the function?
Yes, and temporaries are allowed to bind to const lvalue references. The temporary string v is alive for the duration of the function call.
Note that this is possible because std::string has a implicit converting constructor with a const char* parameter. It is the same constructor that makes this possible:
std::string s = "foo";
I get the error from xcode (3.2.4)/gcc(4.0):
/Users/admin/scm/audacity/mac/../src/toolbars/DeviceToolBar.cpp: In member function 'void DeviceToolBar::ShowInputDialog()':
/Users/admin/scm/audacity/mac/../src/toolbars/DeviceToolBar.cpp:817: error: no matching function for call to 'DeviceToolBar::ShowComboDialog(wxChoice*&, wxString)'
/Users/admin/scm/audacity/mac/../src/toolbars/DeviceToolBar.h:74: note: candidates are: void DeviceToolBar::ShowComboDialog(wxChoice*, wxString&)
So it looks like it expects a reference to a pointer in ShowComboDialog, but I don't know why as the signatures are clearly normal pointers. Furthermore if it was expecting a reference to a pointer the way I am calling it should work.
This is the first error, and there are no special warnings before it.
Also, this compiles in MSVC 2008 express.
Please give me a clue.
//in the class def
//(only relevant portions included
class DeviceToolBar:public ToolBar {
public:
DeviceToolBar();
virtual ~DeviceToolBar();
void ShowInputDialog();
private:
void ShowComboDialog(wxChoice *combo, wxString &title);
wxChoice *mInput;
};
//in the cpp file
void DeviceToolBar::ShowInputDialog()
{
ShowComboDialog(mInput, wxString(_("Select Input Device")));
}
void DeviceToolBar::ShowComboDialog(wxChoice *combo, wxString &title)
{
//...
}
The problem is not the first parameter; its the second. You're passing in a temporary wxString, but the function is expecting a reference. C++ will automatically convert a temporary to a const reference, but it cannot convert it to a reference. You need to make ShowComboDialog take a const reference as its second parameter.
Your ShowComboDialog takes a wxString by non-const reference and you are trying to pass a temporary object as an argument to this parameter. You can only bind const references to temporary objects.
You either need to change ShowComboDialog to take its second argument either by value (wxString) or by const reference (const wxString&) or you need to create a variable for the wxString that you create when you call the function and then pass (a reference to) that variable instead.