The book said I cannot change the value of const once I gave it a number, but it seems I can still give it a number even if it was given.
#include<iostream>
using namespace std;
const int fansc(100);
cout<< fansc << endl; //output:100
int fansc(20);
cout<< fansc << endl;//output:20
The C++ code you gave won't compile, and rightly so. A const variable(a) is, well, ... constant. The error is shown in the following program and transcript:
#include <iostream>
using namespace std;
int main() {
const int fansc(100);
cout << fansc << endl;
int fansc(20);
cout << fansc << endl;
}
pax> g++ --std=c++17 -Wall -Wextra -Wpedantic -o prog prog.cpp
prog.cpp: In function ‘int main()’:
prog.cpp:6:9: error: conflicting declaration ‘int fansc’
6 | int fansc(20);
| ^~~~~
prog.cpp:4:15: note: previous declaration as ‘const int fansc’
4 | const int fansc(100);
| ^~~~~
That leaves the Anaconda bit that you mention in a comment. I have little experience with that but it seems to me the only way that would work is if the second fansc definition was somehow created in a different scope to the first. In real C++ code, that would go something like:
#include <iostream>
using namespace std;
int main() {
const int fansc(100);
cout << fansc << endl;
{ // new scope here
int fansc(20);
cout << fansc << endl;
} // and ends here
cout << fansc << endl;
}
And the output of that is:
pax> g++ --std=c++17 -Wall -Wextra -Wpedantic -o prog prog.cpp && ./prog
100
20
100
(a) Yes, I know that's a self-contradiction :-)
Related
Function foo takes a vector of strings. It's defined as
bool foo(vector<string>& input);
When I call foo with:
foo(vector<string>{"abc"});
my compiler gives the following error:
error: expected '(' for function-style cast or type construction
and points to { as the start of the error. This compiles fine in Xcode but I get the error when running the following via command line with:
g++ -o -std=c++17 main.cpp
What is wrong with my g++ syntax?
G++ Version Information:
g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 11.0.3 (clang-1103.0.32.59)
Target: x86_64-apple-darwin19.4.0
Thread model: posix
Your command line specifies that the output file ("-o") should be called "-std=c++17" – it does not say anything about the language version, so you're compiling as C++03.
Remove the "-o" or add an actual file name.
Also, note that your "g++" is an alias for clang.
I took your code and tried to compile it. For me there was rather problem with trying to pass non const value to function. I changed function argument to const and it compiled and printed without any problem.
#include <iostream>
#include <vector>
bool foo(const std::vector<std::string>& v) {
for (auto& a : v) { std::cout << a << std::endl; }
return true;
}
int main()
{
bool result = foo(std::vector<std::string> {"1", "2", "3" });
// do something with result
return 0;
}
Compiled on: https://www.onlinegdb.com/online_c++_compiler
Function foo expects for an l-value.
You are generating an instance and passing it to the function. But lifetime of the object is not enough for the pass-by-reference call.
Here is an example below; instance of class A is immediately destructed.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class A {
public:
A(int m): m(m) {
cerr << __func__ << endl;
}
~A() {
cerr << __func__ << endl;
}
int m;
};
int main() {
cerr << __func__ << endl;
A(5);
cerr << __func__ << endl;
return 0;
}
Outputs:
main
A
~A
main
This question already has answers here:
Why full specialization of template function is not picked up from the .cpp file without declaration?
(3 answers)
Closed 4 years ago.
Here's my program:
print.hpp:
#pragma once
#include <iostream>
template<size_t p>
void print()
{
std::cout << "" << __FILE__ << "" << __LINE__ << "" << std::endl;
exit(0);
}
print.cpp:
#include "print.hpp"
template<>
void print<13>()
{
std::cout << "Unlucky." << std::endl;
}
main.cpp:
#include <iostream>
#include "print.hpp"
int main()
{
std::cout << "Started." << std::endl;
print<13>();
std::cout << "Exiting." << std::endl;
}
When I compile that with g++ main.cpp print.cpp -O0 -std=c++11 && ./a.out it works fine (output is:
Started.
Unlucky.
Exiting.
).
However, if'd I compile that with g++ main.cpp print.cpp -O1 -std=c++11 && ./a.out it would give me a segmentation fault with the output:
Started.
Unlucky.
Speicherzugriffsfehler //German for memory access error
Almost the same with clang++, without optimization it would do its job just fine
and with -O1 or higher it outputs that:
Started.
Unlucky.
./print.hpp8
Why is that?
You need to declare the template specialization in the .hpp file.
template<size_t p>
void print()
{
std::cout << "" << __FILE__ << "" << __LINE__ << "" << std::endl;
exit(0);
}
// Declare the specialization.
template<> void print<13>();
Without the declaration in the .hpp file, I get a linker error with g++ 6.4.0.
.../Local/Temp/cctCC5MK.o:print.cc:(.text+0x0): multiple definition of `void print<13ul>()'
.../Local/Temp/ccgodRUG.o:socc.cc:(.text$_Z5printILm13EEvv[_Z5printILm13EEvv]+0x0): first defined here
collect2: error: ld returned 1 exit status
I am not sure how you are able to successfully build your program without the declaration.
I'm getting a compiler error when I'm trying to initialize my array with function pointers. Without using a class I'm able to run the code fine, but when I incorporate the code in a class I'm getting the error. I suppose this is more of a problem with my understanding of class usage, the scope resolution operator, etc. Any help to get this resolved would be much appreciated.
#include <iostream>
#include <cassert>
using namespace std;
#define F1 0
#define F2 1
#define F3 2
class A
{
private:
bool Func1();
bool Func2();
bool Func3();
public:
bool do_it(int op);
typedef bool (A::*fn)(void);
static fn funcs[3];
protected:
};
A::fn A::funcs[3] = {Func1, Func2, Func3};
int main()
{
A Obj;
cout << "Func1 returns " << Obj.do_it(F1) << endl;
cout << "Func2 returns " << Obj.do_it(F2) << endl;
cout << "Func3 returns " << Obj.do_it(F3) << endl;
return 0;
}
bool A::do_it(int op)
{
assert(op < 3 && op >= 0);
return (this->*(funcs[op]))();
}
bool A::Func1() { return false; }
bool A::Func2() { return true; }
bool A::Func3() { return false; }
The compiler spits out:
15:35:31 **** Build of configuration Debug for project JT ****
make all
make: Warning: File 'objects.mk' has modification time 7.3 s in the future
Building file: ../src/JT.cpp
Invoking: GCC C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/JT.d" -MT"src/JT.o" -o "src/JT.o" "../src/JT.cpp"
../src/JT.cpp:141:41: error: cannot convert ‘A::Func1’ from type ‘bool (A::)()’ to type ‘A::fn {aka bool (A::*)()}’
A::fn A::funcs[3] = {Func1, Func2, Func3};
^
../src/JT.cpp:141:41: error: cannot convert ‘A::Func2’ from type ‘bool (A::)()’ to type ‘A::fn {aka bool (A::*)()}’
../src/JT.cpp:141:41: error: cannot convert ‘A::Func3’ from type ‘bool (A::)()’ to type ‘A::fn {aka bool (A::*)()}’
src/subdir.mk:18: recipe for target 'src/JT.o' failed
make: *** [src/JT.o] Error 1
15:35:32 Build Finished (took 1s.64ms)
Use A::fn A::funcs[3] = {&A::Func1, &A::Func2, &A::Func3};
Created shared library with below file
example.cpp
#include <iostream>
template <typename T>
T Max (T & a, T & b)
{
return a < b ? b:a;
}
I was trying to use above library in my code
test.cpp
#include <stdio.h>
#include <iostream>
using namespace std;
template int Max <int> (int & a, int & b);
template double Max <double> (double & a, double & b);
int main ()
{
int i = 39;
int j = 20;
cout << "Max(i, j): " << Max(i, j) << endl;
double f1 = 13.5;
double f2 = 20.7;
cout << "Max(f1, f2): " << Max(f1, f2) << endl;
return 0;
}
when I compiled above code ,getting the following error
test.cpp:4: error: explicit instantiation of non-template ‘int Max’
test.cpp:4: error: expected ‘;’ before ‘<’ token
test.cpp:5: error: explicit instantiation of non-template ‘double Max’
test.cpp:5: error: expected ‘;’ before ‘<’ token
test.cpp: In function ‘int main()’:
test.cpp:11: error: ‘Max’ was not declared in this scope*
I realize this is a trivial example more for academic purpose than anything else. Otherwise I would recommend scrapping the whole thing and just using std::max from the get-go. The standard library provides a wealth of well-specified and tested functionality for the taking; use it unless you have a damn good reason to reinvent the wheel.
If you seriously want to provide a template declaration of a function in a header, and provide the implementation of said-template in a shared object library, you can do it by using explicit instantiation, which it appears you're attempting. However, your attempt appears to be putting said-same in the wrong module.
One way to do it is as follows:
example.hpp
#ifndef MYLIB_EXAMPLE_HPP
#define MYLIB_EXAMPLE_HPP
// define forward declaration here. no implementation
template<class T> T Max(T lhs, T rhs);
#endif
example.cpp
#include "example.hpp"
// provide implementation here
template<class T>
T Max(T lhs, T rhs)
{
return (lhs < rhs) ? rhs : lhs;
}
// explicit instantiations
template int Max<int>(int,int);
template double Max<double>(double,double);
That's it for the library. An example build using clang would be:
clang++ -std=c++11 -Wall -Wextra -pedantic -fPIC -shared -o libexample.so example.cpp
The resulting shared object library exposes the following symbols:
nm libexample.so
0000000000000f50 T __Z3MaxIdET_S0_S0_
0000000000000f20 T __Z3MaxIiET_S0_S0_
U dyld_stub_binder
so as you can see, they're there in the lib. On to the test program that will consume this library:
test.cpp
#include <iostream>
#include "example.hpp"
int main ()
{
int i = 39;
int j = 20;
std::cout << "Max(i, j): " << Max(i, j) << std::endl;
double f1 = 13.5;
double f2 = 20.7;
std::cout << "Max(f1, f2): " << Max(f1, f2) << std::endl;
return 0;
}
We build it as follows (assuming the library is in the local folder):
clang++ -std=c++11 -Wall -Wextra -pedantic -L. -o test -lexample test.cpp
The resulting program, test, produces the following output:
Max(i, j): 39
Max(f1, f2): 20.7
Honestly, there isn't a ton of value in doing it this way, as any future usages of Max that are not provided in your explicit list will result in linker errors (unless that is the intent, in which case it would do exactly what you're looking for).
My recomendations:
Change example.cpp to header a file, Max is a template function
Remove the forward declarations in the code
Remove #include <stdio.h>, unless that really is used somewhere
example.hpp:
template <typename T>
T Max (T& a, T& b)
{
return a < b ? b : a;
}
test.cpp:
#include <iostream>
using namespace std;
int main ()
{
int i = 39;
int j = 20;
cout << "Max(i, j): " << Max(i, j) << endl;
double f1 = 13.5;
double f2 = 20.7;
cout << "Max(f1, f2): " << Max(f1, f2) << endl;
return 0;
}
I seem to be getting several errors with
map<string,function<XMLSerializable*()>> mapConstructor;
Notably,
la5.cpp: In function ‘int main(int, char**)’:
la5.cpp:21:13: error: ‘function’ was not declared in this scope
la5.cpp:21:43: error: ‘mapConstructor’ was not declared in this scope
la5.cpp:21:43: error: template argument 2 is invalid
la5.cpp:21:43: error: template argument 4 is invalid
la5.cpp:25:58: warning: lambda expressions only available with -std=c++0x or - std=gnu++0x [enabled by default]
la5.cpp:33:26: error: expected primary-expression before ‘*’ token
la5.cpp:33:28: error: expected primary-expression before ‘)’ token
la5.cpp:33:31: error: ‘pFunc’ was not declared in this scope
make: *** [la5.o] Error 1
Unfortunately, I can't seem to find what I've done wrong, as it seems to deal with that map declaration which was given to the class by my instructor. Below is my .cpp
#include <iostream>
#include <map>
#include <string>
#include <functional>
#include "Armor.h"
#include "Weapon.h"
#include "Item.h"
#include "Creature.h"
using namespace std;
XMLSerializable * constructItem()
{
return new Item;
}
int main(int argc, char * argv[])
{
map<string,function<XMLSerializable*()>> mapConstructor;
mapConstructor["Item"] = constructItem;
mapConstructor["Creature"] = []() {return new Creature; };
cout << "Input the class name, then we'll try to construct it." << endl;
string sLookup = " ";
cin >> sLookup;
function<XMLSerializable*()> pFunc = mapConstructor[sLookup];
if(pFunc() == NULL)
{
cout << "Sorry, the object couldn't be constructed." << endl;
}
else
{
cout << pFunc() << " a non NULL value was returned!" << endl;
}
return 0;
}
Any suggestions? I'm unfamiliar with maps, but I believe this should work, right?
Coding in pico, compiling with a makefile using g++.
It looks like you just are forgetting to add -std=c++11 or -std=c++0x to your compiler flags to enable C++11.
-std=c++0x is deprecated, but on older versions of g++, -std=c++11 is not available.