Adding to a Protocol Buffers repeated field - c++

I'm working in C++ with a Protocol Buffer template including the following message:
message StringTable {
repeated bytes s = 1;
}
I'm attempting to add a new value to the existing data, like so:
pb.stringtable().s().Add(replace_key);
However, this generates an error on compilation (using clang on OS X):
test.cpp:51:4: error: member function 'Add' not viable: 'this' argument
has type 'const ::google::protobuf::RepeatedPtrField< ::std::string>',
but function is not marked const
pb.stringtable().s().Add(replace_key);
^~~~~~~~~~~~~~~~~~~~
Any clues? I'm very much a C++ newbie so may be making a dumb error.
Edit:
Using the accessors produces a similar error:
pb.stringtable().add_s(replace_key);
results in:
test.cpp:51:21: error: no matching member function for call to 'add_s'
pb.stringtable().add_s(replace_key);
~~~~~~~~~~~~~~~~~^~~~~
./osmformat.pb.h:3046:26: note: candidate function not viable: 'this' argument has type 'const ::StringTable', but method is not marked const
inline void StringTable::add_s(const ::std::string& value) {
^
./osmformat.pb.h:3050:26: note: candidate function not viable: 'this' argument has type 'const ::StringTable', but method is not marked const
inline void StringTable::add_s(const char* value) {
^
./osmformat.pb.h:3043:36: note: candidate function not viable: requires 0 arguments, but 1 was provided
inline ::std::string* StringTable::add_s() {
^
./osmformat.pb.h:3054:26: note: candidate function not viable: requires 2 arguments, but 1 was provided
inline void StringTable::add_s(const void* value, size_t size) {

Problem solved.
The existing StringTable isn't mutable by default. However, using the mutable_ accessors makes it so:
pb.mutable_stringtable().add_s(replace_key);

Related

In C++, when no constructor is declared for a class, what will happen if I construct an object with arguments?

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.

What does this mean? : note: no known conversion for argument 1 from ‘int’ to ‘const account&’

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

Thread for member functions

I was trying to make threads for the following function
void SortingCompetition::masterSort(int low, int high)
like this:
thread a(&SortingCompetition::masterSort,this, low, j-1);
thread b (&SortingCompetition::masterSort,this, j+1,high);
and get the following error.
sortingcompetition.cpp:55:16: error: no matching constructor for initialization
of 'std::__1::thread'
thread b (&SortingCompetition::masterSort,this, j+1,high);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:374:9: note:
candidate constructor template not viable: requires single argument '__f',
but 4 arguments were provided
thread::thread(_Fp __f)
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:263:5: note:
candidate constructor not viable: requires 1 argument, but 4 were provided
thread(const thread&);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:270:5: note:
candidate constructor not viable: requires 0 arguments, but 4 were
provided
thread() _NOEXCEPT : __t_(0) {}
I'm new to threads, so I'm not sure what to do.
You have to bind the method like:
thread a(std::bind(&SortingCompetition::masterSort, this, std::placeholders::_1, std::placeholders::_2),low,j-1);
Alternative you can use a function or static method. The reason is, that due binding the this pointer is preserved. To invoke the method of an instance wich is not static, you need the this pointer. With std::bind this is done. std::bind needs to now how many parameters the method has, thats where the placeholder come into game.

How do I create an object variable from a function call?

We are using an custom image class written by our professor. I can load images like this
SimpleGrayImage in("images/uni01.pgm");
Now I have a function that looks like this
SimpleGrayImage apply_mask(SimpleGrayImage &img,SimpleFloatImage &mask){
and I can also uses methods on it like this apply_mask(...).show();
But I am not allowed to do this SimpleGrayImage img = apply_mask(...);
Did I miss something or could it be that our professor forgot to add another constructor?
test.cpp:133:43: error: no matching function for call to ‘SimpleGrayImage::SimpleGrayImage(SimpleGrayImage)’
SimpleGrayImage img = apply_mask(in,mask);
^
test:133:43: note: candidates are:
In file included from SimpleFloatImage.h:13:0,
from aufgabe11_12_13.cpp:13:
SimpleGrayImage.h:110:2: note: SimpleGrayImage::SimpleGrayImage(const string&)
SimpleGrayImage(const std::string& filename);
^
SimpleGrayImage.h:110:2: note: no known conversion for argument 1 from ‘SimpleGrayImage’ to ‘const string& {aka const std::basic_string<char>&}’
SimpleGrayImage.h:91:2: note: SimpleGrayImage::SimpleGrayImage(SimpleGrayImage&)
SimpleGrayImage(SimpleGrayImage &img);
^
SimpleGrayImage.h:91:2: note: no known conversion for argument 1 from ‘SimpleGrayImage’ to ‘SimpleGrayImage&’
SimpleGrayImage.h:86:2: note: SimpleGrayImage::SimpleGrayImage(int, int)
SimpleGrayImage(int wid, int hig);
^
SimpleGrayImage.h:86:2: note: candidate expects 2 arguments, 1 provided
SimpleGrayImage.h:80:2: note: SimpleGrayImage::SimpleGrayImage()
SimpleGrayImage();
^
SimpleGrayImage.h:80:2: note: candidate expects 0 arguments, 1 provided
From the errors i can see that the copy constructor is not defined correctly:
SimpleGrayImage::SimpleGrayImage(SimpleGrayImage&)
This will not be called since the value you return from function apply_mask is not local variable but an rvalue.
For the constructor to take rvalues you need to change the signature of the copy constructor to
SimpleGrayImage::SimpleGrayImage(const SimpleGrayImage&)//note the new const
Edit: For more information on rvalues you can check this link. Rvalues can be converted to const SimpleGrayImag& a = apply_mask() because the const ensures that you can't make changes to a so the compiler can safely give you the address of that local memory. The definition without const can only be used on lvalues like such:
SimpleGrayImag a;//this is an lvalue;
SimpleGrayImag b = a;
The best approach is to use const on all the arguments that you don't want them to be output arguments. Also you can make functions with both versions const and non const and most of the time the compiler will understands you, however it should be avoided because the code is harder to read and understand.

Setting a std::function variable to refer to the std::sin function

I've got a question about how to properly use the new C++11 std::function variable. I've seen several examples from searching the Internet, but they don't seem to cover the usage case I'm considering. Take this minimum example, where the function fdiff is an implementation of the finite forward differencing algorithm defined in numerical.hxx (which isn't the problem, I just wanted to give a contextual reason why I'd want to take an arbitrary function and pass it around).
#include <functional>
#include <iostream>
#include <cmath>
#include "numerical.hxx"
int main()
{
double start = 0.785398163;
double step = 0.1;
int order = 2;
std::function<double(double)> f_sin = std::sin;
std::cout << fdiff(start, step, order, f_sin) << std::endl;
return 0;
}
Attempting to compile the above program gives me the error (in clang++)
test.cpp:11:32: error: no viable conversion from '<overloaded function type>' to
'std::function<double (double)>'
std::function<double(double)> f_sin = std::sin;
^ ~~~~~~~~
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.1/../../../../include/c++/4.7.1/functional:2048:7: note:
candidate constructor not viable: no overload of 'sin' matching
'nullptr_t' for 1st argument
function(nullptr_t) noexcept
^
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.1/../../../../include/c++/4.7.1/functional:2059:7: note:
candidate constructor not viable: no overload of 'sin' matching 'const
std::function<double (double)> &' for 1st argument
function(const function& __x);
^
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.1/../../../../include/c++/4.7.1/functional:2068:7: note:
candidate constructor not viable: no overload of 'sin' matching
'std::function<double (double)> &&' for 1st argument
function(function&& __x) : _Function_base()
^
/usr/lib/gcc/x86_64-unknown-linux-gnu/4.7.1/../../../../include/c++/4.7.1/functional:2092:2: note:
candidate template ignored: couldn't infer template argument '_Functor'
function(_Functor __f,
^
1 error generated.
or from g++
test.cpp: In function ‘int main()’:
test.cpp:11:45: error: conversion from ‘<unresolved overloaded function type>’ to non-scalar type ‘std::function<double(double)>’ requested
As I understand the problem, it's because std::sin is implemented as a template class in the standard library, but I can't seem to figure out what I need to do to give enough of a specialization to get a function reference. I've also tried various things like using the new auto keyword, using &std::sin to get a pointer, etc., but they all give me the same type of error.
std::sin is an overloaded function: you must disambiguate which std::sin overload you mean:
std::function<double(double)> f_sin = (double(*)(double))&std::sin;
There are some cases where the compiler can disambiguate overloaded functions (e.g., if f_sin was of type double(*)(double), the cast would not be required). However, this is not one of those cases.
With lambda you will be always on safe side:
std::function<double(double)> f_sin = [](double arg) -> double { return std::sin(arg); };
Actually you can do better, if you can change fdiff or it is already accepting template parameter - not just std::function<double(double)>:
auto f_sin = [](double arg) -> double { return std::sin(arg); };
std::cout << fdiff(start, step, order, f_sin) << std::endl;
[UPDATE] This answer is new version, previous advice to use function template specialization was incorrect, since std::sin is not function template but set of overloaded functions.