I am following along a course about modern C++. I get an error with explicit unique_handle function. It says m_value is unknown override specifier? I listed the value above it shows still be in variable space.
explicit unique_handle(pointer value = Traits::invalid()) throw()
m_value { value }
{
}
https://pastebin.com/MA4vnWR3
You are missing a colon ':' before m_value, which denotes the start of the inializer list:
explicit unique_handle(pointer value = Traits::invalid()) throw()
: m_value { value }
{
}
Related
I'm calling unordered_map::emplace() and I am storing the returned value (a pair). I just want to access the inserted value from the pair but for the life of me I cannot figure out the correct configuration of this confusing pair.
My unordered map definition:
std::unordered_map<GUID, shared_ptr<Component>> components;
I've looked at the unordered_map::emplace() documentation; according to this the first element in the pair should be the shared_ptr<Component> but the compiler is just not happy.
In the below code I get the error: Error 2 error C2227: left of '->gUid' must point to class/struct/union/generic type
class Component {
public:
template<typename T, typename... Params>
GUID addComponent(Params... params)
{
auto cmp = Component::create<T>(params...);
auto res = components.emplace(cmp->gUid, cmp);
if (!res.second) {
GUID gUid;
getNullGUID(&gUid);
return gUid;
}
return (*res.first)->gUid; // compiler error here
// *Yes I know I can do: return cmp->gUid;
}
GUID gUid; // initialised in constructor
std::unordered_map<GUID, std::shared_ptr<Component>> components;
};
Any idea how to correctly access the pairs second value?
The first of the pair returned from emplace is an iterator -- which, for unordered_map, acts like a pointer to a pair<key, value>. So to get the value from that pair, you need second:
return res.first->second->gUid;
I've come across this "feature" in MSVC++ and I'm now not sure if it's a bug or my understanding of lvalues/rvalues in C++ is just plain wrong.
I've added some seriously dumbed-down code to illustrate, but basically the issue is that MSVC++ 2013 (both base and NOV 2013 CTP compilers) allows assignment to temporary objects, which should really be rvalues and hence disallow any assignment attempts at compile time.
#include <iostream>
struct account {
int value;
explicit account(int v) : value{ v } {
std::cout << "account ctor: " << value << std::endl;
}
account(const account & acc) : value{ acc.value } {
std::cout << "account copy ctor" << std::endl;
}
account(account && acc) : value{ acc.value } {
std::cout << "account move ctor" << std::endl;
}
account & operator=(const account & acc) {
value = acc.value;
std::cout << "account copy assign" << std::endl;
return *this;
}
account & operator=(account && acc) {
value = acc.value;
std::cout << "account move assign" << std::endl;
return *this;
}
};
int get_int() { return 42; }
account get_account() {
return account(123);
}
int main() {
//get_int() = 5; // this predictably fails to compile
// with '=' : left operand must be l-value
// everything below succeeds
get_account() = account(42); // console trace for this
// account ctor: 42
// account ctor: 123
// account move assign
account(123) = account(42); // console trace same as above
account acc(0); // account ctor: 0
account(42) = acc; // account ctor: 42
// account copy assign
get_account() = acc; // console trace same as above
}
Surely get_account() = acc; or account(42) = acc; is not C++ Standard's prescribed behaviour?! Both get_account() & account(42) should result in rvalues, which by definition do not allow assignments.
Incidentally, overloading member functions based on lvalue/rvalue qualifiers
...
void memberFn() const &;
void memberFn() &&;
...
which is supported in NOV 2013 CTP is not working properly or at all. I assume this is a result of failing to recognise rvalues, so that this is always an lvalue.
PS Unfortunately, I do not have an opportunity to test this with other compilers.
According to my understanding, this is perfectly valid C++11.
Only built-in assignment to prvalues is prohibited.
From [5, expr]:
Note: Operators can be overloaded, that is, given meaning when applied to expressions of class type (Clause
9) or enumeration type (7.2). Uses of overloaded operators are transformed into function calls as described
in 13.5. Overloaded operators obey the rules for syntax specified in Clause 5, but the requirements of
operand type, value category, and evaluation order are replaced by the rules for function call.
So the requirements on
get_account() = account(42);
are the same as on any other member-function call
get_account().foo_bar(account(42));
which makes sense since it is just a nicer syntax for
get_account().operator=(account(42));
The section 3.10 on Lvalues and rvalues makes this as clear well [basic.lval]:
For example, the built-in assignment operators expect that the left operand is an lvalue and that the right operand is a prvalue and yield an lvalue as the result. User-defined operators are functions, and the categories of values they expect and yield are determined by their parameter and return
types.
This question already has answers here:
How to test whether stringstream operator>> has parsed a bad type and skip it
(5 answers)
Closed 8 years ago.
I am a little new to C++ and would really appreciate any input or suggestions! So with our intro course projects I have been looking for a way to ensure that when the prog. is asking for int values it correctly responds! That is it states its invalid in cases of both a double as well as string being entered! So if cin >> intVariable ... intVariable will not accept cin entry of "abdf" or 20.01.
So to achieve this I wrote the following function...It works but I am looking for your thoughts on how this process can be further improved!
void getIntegerOnly(int& intVariable, string coutStatement)
{
bool isInteger; // Check if value entered by user is int form or not
string tmpValue; // Variable to store temp value enetered by user
cout << coutStatement; // Output the msg for the cin statement
do
{
cin >> tmpValue; // Ask user to input their value
try // Use try to catch any exception caused by what user enetered
{
/* Ex. if user enters 20.01 then the if statement converts the
string to a form of int anf float to compare. that is int value
will be 20 and float will be 20.01. And if values do not match
then user input is not integer else it is. Keep looping untill
user enters a proper int value. Exception is 20 = 20.00 */
if (stoi(tmpValue) != stof(tmpValue))
{
isInteger = false; // Set to false!
clear_response(); // Clear response to state invalid
}
else
{
isInteger = true; //Set to true!
clear_cin(); // Clear cin to ignore all text and space in cin!
}
}
catch (...) // If the exception is trigured!
{
isInteger = false; // Set to false!
clear_response(); // Clear response to state invalid
}
} while (!isInteger); //Request user to input untill int clause met
//Store the int value to the variable passed by reference
intVariable = stoi(tmpValue);
}
This is simply an example of getting users age and age is greater than zero when running a Win32 console based application! Thank you for the feedback :)
One way would be something like the following:
std::string str;
std::cin >> str;
bool are_digits = std::all_of(
str.begin(), str.end(),
[](char c) { return isdigit(static_cast<unsigned char>(c)); }
);
return are_digits ? std::stoi(str) : throw std::invalid_argument{"Invalid input"};
and catch the exceptions on the calling side (stoi can also throw std::out_of_range).
You can leverage the second parameter of stoi().
string tmpValue;
size_t readChars;
stoi(tmpValue, &readChars);
if(readChars == tmpValue.length())
{
// input was integer
}
EDIT: this will not work for strings containing "." (for example integers passed in scientific notation).
This is not my work, but the answer to this question is what you want. Pass the string to it as a reference. It will return true is your string is an integer.
How do I check if a C++ string is an int?
I am in the process of learning D (I decided it would be a better beginner friendly language than C++) and I decided to give myself the excercise of implementing a general quicksort in D. My program runs fine when sorting integers but it doesn't compile and throws a strange error when sorting strings.
Here is my code:
import std.stdio, std.algorithm;
T[] quickSort(T)(T[] input) {
if (input.length <= 1) {return input;}
ulong i = input.length/2;
auto pivot = input[i];
input = input.remove(i);
T[] lesser = [];
T[] greater = [];
foreach (x; input) {
if (x<=pivot)
{
lesser ~= x;
}
else
{
greater ~=x;
}
}
return (quickSort(lesser) ~ cast(T)pivot ~ quickSort(greater));
}
void main() {
//Sort integers, this works fine
//writeln(quickSort([1,4,3,2,5]));
//Sort string, throws weird error
writeln(quickSort("oidfaosnuidafpsbufiadsb"));
}
When I run it on a string it throws this error:
/usr/share/dmd/src/phobos/std/algorithm.d(7397): Error: template std.algorithm.move does not match any function template declaration. Candidates are:
/usr/share/dmd/src/phobos/std/algorithm.d(1537): std.algorithm.move(T)(ref T source, ref T target)
/usr/share/dmd/src/phobos/std/algorithm.d(1630): std.algorithm.move(T)(ref T source)
/usr/share/dmd/src/phobos/std/algorithm.d(1537): Error: template std.algorithm.move cannot deduce template function from argument types !()(dchar, dchar)
/usr/share/dmd/src/phobos/std/algorithm.d(7405): Error: template std.algorithm.moveAll does not match any function template declaration. Candidates are:
/usr/share/dmd/src/phobos/std/algorithm.d(1786): std.algorithm.moveAll(Range1, Range2)(Range1 src, Range2 tgt) if (isInputRange!(Range1) && isInputRange!(Range2) && is(typeof(move(src.front, tgt.front))))
/usr/share/dmd/src/phobos/std/algorithm.d(7405): Error: template std.algorithm.moveAll(Range1, Range2)(Range1 src, Range2 tgt) if (isInputRange!(Range1) && isInputRange!(Range2) && is(typeof(move(src.front, tgt.front)))) cannot deduce template function from argument types !()(string, string)
helloworld.d(9): Error: template instance std.algorithm.remove!(cast(SwapStrategy)2, string, ulong) error instantiating
helloworld.d(31): instantiated from here: quickSort!(immutable(char))
helloworld.d(31): Error: template instance helloworld.quickSort!(immutable(char)) error instantiating
the problem is that strings are immutable so remove won't work (as it manipulates the string)
you can fix that by not removing and not inserting the pivot in the concat:
auto pivot = input[i];
//input = input.remove(i); //<- remove this line
T[] lesser = [];
//...
return (quickSort(lesser) ~ quickSort(greater)); //<- remove cast(T)pivot ~
or by passing in a dup:
writeln(quickSort("oidfaosnuidafpsbufiadsb".dup));
You have to put a "d" behind the string to make it utf-32, otherwise remove won't accept it.
writeln(quickSort("oidfaosnuidafpsbufiadsb"d.dup));
I create a constructor as follow
Form1(array<System::String ^> ^args) //HW5
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
if (args->Length==0){
CregArray = gcnew array<CRegistration^>(100);
record_number = 0;
}
else {
}
}
After that I use a line of code to create the constructor. Basically, I want to use the case of length==0, but the compiler said there is an error. I don't understand what the compiler means.
Application::Run(gcnew Form1(""));
The error is "Error 1 error C2664: 'Project3::Form1::Form1(cli::array ^)' : cannot convert parameter 1 from 'const char [1]' to 'cli::array ^'
You are passing in a string where an array of strings is expected.
Also, String::Empty is better practice than using a literal empty string.
Try this:
array<System::String^>^ args = gcnew array<System::String^>(1);
args[0] = String::Empty;
Application::Run(gcnew Form1(args));