I have the following code:
test.cpp
#include <iostream>
using namespace std;
class [[warn_unused]] test{
int val;
public:
test() {
val = 0;
}
int getv() { return this->val; }
~test() {
cout << "end\n";
}
};
int main() {
test t1;
int t2 = t1.getv();
return 0;
}
I get the following warnings from the compiler on running g++ test.cpp. My g++ version is 9.2.1.
test.cpp:4:23: warning: ‘warn_unused’ attribute directive ignored [-Wattributes]
4 | class [[warn_unused]] test{
|
If I change the attribute to [[gnu::warn_unused]], then there are no warnings whether I use the class or not.
Related
I look this example and practice it:
https://novus.pixnet.net/blog/post/23784820
(The code is at the end)
The compile command is:
g++ sc.cc main.cc -o main.exe
I have 2 questions:
The Compilation Unit has 2 unit which consist of sc and main. (correct?)
I know this example (Schwarz Counter) is applied to iostream (C++).Singleton pattern looks suitable for this situation. Does Singleton pattern is better than Schwarz Counter in the case for unique and global (such as file io)?
Code:
sc.h
#include <fstream>
class Log {
friend class Initializer;
public:
void Print(const char* msg) {
std::fputs(msg, onlyFile_);
}
private:
static std::FILE* onlyFile_;
};
class Initializer {
public:
Initializer();
~Initializer();
private:
static int ref_;
};
extern Log log;
static Initializer init;
#endif
sc.cc
#include "s.h"
std::FILE* Log::onlyFile_ = 0;
int Initializer::ref_ = 0;
Initializer::Initializer() {
if (0 == ref_++) {
Log::onlyFile_ = fopen("somefile.txt", "w");
}
}
Initializer::~Initializer() {
if (0 == --ref_) {
fclose(Log::onlyFile_);
}
}
main.c
#include "s.h"
int main(int argc, char const *argv[]) {
log.Print("aa");
return 0;
}
I have the following simple program:
#include <iostream>
class foo
{
int a;
} foo;
int main()
{
foo.a = 42;
std::cout << foo.a;
}
It outputs "42" but it shouldn't, as a is clearly private as class members are private by default. I have G++ 5.3.1 is this a bug?
Here is a mini-example of my code, how to correctly initialize member pool_ in the constructor.
#include <vector>
#include <thread>
#include <iostream>
namespace b {
class A;
typedef void (A::*Func) (void);
struct c {
Func fun;
int num;
std::vector<std::thread> threads;
};
class A {
public:
A() {
pool_ = {{&A::func1, 1, }, {&A::func2, 2, }}; // how to initialize?
}
private:
std::vector<c> pool_;
void func1(void) { std::cout << "func1\n"; };
void func2(void) { std::cout << "func2\n"; };
void CreateThread(c& pool) {
for (int i = 0; i < pool.num; ++i) {
pool.threads.push_back(std::thread(pool.fun, this));
}
}
};
} // namespace b
int main() {
b::A a;
return 0;
}
Platform: Ubuntu 14.04 with g++ 4.8.4
compile command:
g++ -Wall -std=c++11 test.cc -lpthread -o test
The major error message is:
error: use of deleted function ‘std::thread::thread(std::thread&)’
I know it is because copy construction and assignment of std::thread is not allowed. But I tried other ways and failed.
Two steps to solving this elegantly:
provide a constructor for c that does 'the right thing'
struct c {
c(Func fun, int num, std::vector<std::thread> threads = {})
: fun(fun)
, num(num)
, threads(std::move(threads))
{}
Func fun;
int num;
std::vector<std::thread> threads;
};
Then neatly emplace your objects into pool_
A()
{
pool_.emplace_back(&A::func1, 1);
pool_.emplace_back(&A::func2, 2);
}
The following Code compiles using both Debug\Win32 and Debug \ x64 settings in VC2013, but when I use Debug \ x64 i get the following IntelliSense Error:
IntelliSense: no operator "=" matches these operands
operand types are: std::future<bar<int>> = std::future<bar<int> (&)(bar<int> v)>
The Error refers to this function in Header.cpp:
bar<int> test::call(bar<int> v)
{
std::future<bar<int>> ret;
ret = std::async(std::launch::async, &test::exec, this, v);
return ret.get();
}
Why does std::async return something diffrent when using x64?
return value win32:
std::future<bar<int>>
return value x64:
std::future<bar<int> (&)(bar<int>
How can i fix this for x64?
My Code:
Header.h
#pragma once
#include <future>
#include <iostream>
using namespace std;
template <typename T>
class bar
{
public:
bar()
{
state = 9;
}
void dec(){ state--; }
T show()
{
return state;
}
private:
T state;
};
class test{
public:
test(int a);
public:
bar<int> call(bar<int> v);
private:
bar<int> exec(bar<int> v);
private:
int value;
};
Header.cpp
#include "Header.h"
using namespace std;
test::test(int a)
{
value = a;
}
bar<int> test::call(bar<int> v)
{
std::future<bar<int>> ret;
ret = std::async(std::launch::async, &test::exec, this, v);
return ret.get();
}
bar<int> test::exec(bar<int> v)
{
v.dec();
v.dec();
return v;
}
Source.cpp
#include <future>
#include <iostream>
#include "Header.h"
using namespace std;
int main()
{
test object(4);
bar<int> foo;
bar<int> other = object.call(foo);
std::cout << other.show();
getchar();
}
Edit:
I do not want to use auto, because auto would not work in other scenarios (for example creating a vector of futures and then pushing back futures)
This Error is NOT a compiler error, the code compiles and executes flawlesly ==> i can't post the compiler error because there is no compiler error. I just want to get rid of the VC IntelliSense Error
Using std::move() does not solve the problem, i still get an IntelliSense Error:
(The Code compiles and executes perfectly with and without the use of std::move)
IntelliSense: no operator "=" matches these operands
operand types are: std::future<bar<int>> = std::future<bar<int> (&)(bar<int> v)>
... and save it into self-defined object type? I'm using PostgreSQL. When I have everything in one file, it works. But I wanted to split this into class-files like you always do when writing in cpp. When I divided my code into *.h and *.cpp files, I'm getting errors.
Here are my files:
test.h
class MyInt
{
public:
MyInt();
MyInt(int i);
void set(int i);
int get() const;
private:
int i_;
};
test.cpp
#include "test.h"
#include <soci.h>
#include <postgresql/soci-postgresql.h>
MyInt::MyInt()
{
}
MyInt::MyInt(int i)
{
this->i_ = i;
}
int MyInt::get() const
{
return this->i_;
}
void MyInt::set(int i)
{
this->i_ - i;
}
namespace soci
{
template <>
struct type_conversion<MyInt>
{
typedef int base_type;
static void from_base(int i, soci::indicator ind, MyInt & mi)
{
if (ind == soci::i_null)
{
throw soci_error("Null value not allowed for this type");
}
mi.set(i);
}
static void to_base(const MyInt & mi, int & i, soci::indicator & ind)
{
i = mi.get();
ind = soci::i_ok;
}
};
}
main.cpp
#include <iostream>
#include "test.h"
int main(int argc, char **argv)
{
MyInt i;
sql.open(soci::postgresql, "dbname=mydb user=postgres password=postgrespass");
sql << "SELECT count(*) FROM person;", soci::into(i);
std::cout << "We have " << i.get() << " persons in the database.\n";
sql.close();
return 0;
}
I compile it like this:
g++ main_test.cpp test.h test.cpp -o App -lsoci_core -lsoci_postgresql
-ldl -lpq -I /usr/local/include/soci -I /usr/include/postgresql
and got those errors:
In file included from /usr/local/include/soci/into-type.h:13:0,
from /usr/local/include/soci/blob-exchange.h:12,
from /usr/local/include/soci/soci.h:18,
from main_test.cpp:3:
/usr/local/include/soci/exchange-traits.h: In instantiation of â€soci::details::exchange_traits<MyInt>’:
/usr/local/include/soci/into.h:29:60: instantiated from â€soci::details::into_type_ptr soci::into(T&) [with T = MyInt, soci::details::into_type_ptr = soci::details::type_ptr<soci::details::into_type_base>]’
main_test.cpp:29:59: instantiated from here
/usr/local/include/soci/exchange-traits.h:35:5: error: incomplete type â€soci::details::exchange_traits<MyInt>’ used in nested name specifier
THE ABOVE PROBLEM IS SOLVED, TAKE A LOOK AT #JohnBandela ANSWER.
The code where you specialize type_conversion
template<>
struct type_conversion<MyInt>
Needs to be in test.h not test.cpp. The problem is if you have it in test.cpp like you do now, it is not visible in main.cpp where you are using SOCI