使用字符串和 int(类似)类型初始化模板的静态成员 class
Initializing static member of a template class with both string and int(like) types
我正在尝试实现一个监视器 class 来处理多线程。我必须使用 Visual Studio 2010,所以我没有 c++11。我可以通过创建全局变量来简单地做到这一点,我将跨线程 reading/writing 为每种类型的值一个,并为每个单独的值使用互斥锁,这很简单但更乏味。
所以我想花点时间在 Class 中实现监视器概念。
这项工作在某种程度上是 "done",因为数据类型是 float 或 int,但我想更进一步并实现监视器 class 以支持 C 标准类型和 c++ class es,比如字符串。
我的方法是让静态成员作为跨线程的共享内存工作,这样我唯一要做的就是在两个线程中实例化 class 并且我会正确设置 IPC。
事情是...我必须初始化静态成员,但我无法让它工作,因为字符串和 int-ish 类型(int、float 等...)没有以相同的方式初始化。
这是我尝试做的事情:
template<class T>
class Monitor : protected Mutex {
public:
Monitor(bool Verbose);
~Monitor();
T read(DWORD wait_time=INFINITE);
void write(T value, DWORD wait_time=INFINITE);
//friend void operator= (Monitor& m1, Monitor& m2);
private:
static T container;
};
template<class T>
T Monitor<T>::container = (typeid(T) == typeid(string) ? "" : 0);
如果我只声明了 Monitor<string> pMonitor2(VERB_ON);
或 Monitor<int> pMonitor1(VERB_ON);
,它就可以正常工作。声明两者都会抛出我 error C2440: 'initializing' : cannot convert from 'const char *' to 'int'
.
此外,在 classes 中实现这种进程间通信概念的最佳方法是什么?
到目前为止的完整代码:
monitor.cpp:
#include "monitor.h"
using namespace std;
HANDLE Mutex::hMutex = nullptr;
unsigned int Mutex::counter = 0;
Mutex::Mutex(bool V) {
Verbose = V;
if(hMutex == nullptr) {
if(Verbose) cout << "Creating mutex\n";
hMutex = CreateMutex(
NULL,
FALSE,
(LPCWSTR) "CONTMUTEX");
counter++;
}
else{
if(Verbose) cout <<"Mutex already created\n";
counter++;
}
}
Mutex::~Mutex() {
counter--;
if(counter == 0) {
if(Verbose) cout << "Destroying mutex\n";
CloseHandle(hMutex);
}
else {
if(Verbose) cout << "Awaiting closure of all instances of Mutex\n";
}
}
/*void operator= (Monitor& m1, Monitor& m2) {
m1.write(m2.read());
}*/
monitor.h:
#ifndef MONITOR_INC
#define MONITOR_INC
//#include <vector>
#include <Windows.h>
#include <iostream>
using namespace std;
enum verb{VERB_OFF, VERB_ON};
class Mutex {
public:
Mutex(bool Verbose);
~Mutex();
protected:
bool Verbose;
static HANDLE hMutex;
static unsigned int counter;
};
template<class T>
class Monitor : protected Mutex {
public:
Monitor(bool Verbose);
~Monitor();
T read(DWORD wait_time=INFINITE);
void write(T value, DWORD wait_time=INFINITE);
//friend void operator= (Monitor& m1, Monitor& m2);
private:
static T container;
};
template<class T>
T Monitor<T>::container = (typeid(T) == typeid(string) ? "" : 0);
template<class T>
Monitor<T>::Monitor(bool Verbose) : Mutex(Verbose) {
if(Verbose) cout << "Monitor Constructor\n";
}
template<class T>
Monitor<T>::~Monitor() {
if(Verbose) cout << "Monitor Destructor\n";
}
template<class T>
T Monitor<T>::read(DWORD wait_time) {
T ret_val;
WaitForSingleObject(hMutex, wait_time);
ret_val = container;
ReleaseMutex(hMutex);
return ret_val;
}
template<class T>
void Monitor<T>::write(T value, DWORD wait_time) {
WaitForSingleObject(hMutex, wait_time);
container = value;
ReleaseMutex(hMutex);
}
//void operator= (Monitor& m1, Monitor& m2);
#endif
main.cpp 用于测试:
#include "monitor.h"
#include <string>
#include <sstream>
int main() {
Mutex pMutex1(VERB_ON);
Mutex pMutex2(VERB_ON);
Mutex pMutex3(VERB_ON);
Monitor<int> pMonitor1(VERB_ON);
cout << pMonitor1.read() << "\n";
pMonitor1.write(20);
cout << pMonitor1.read() << "\n";
Monitor<string> pMonitor2(VERB_ON);
cout << pMonitor2.read() << "\n";
pMonitor2.write("TURN DOWN FOR WHAT");
cout << pMonitor2.read() << "\n";
return 0;
}
对于任何不好的做法,我必须事先道歉。自从我上次使用 C++ 编码以来已经过去了大约 8 个月,我借此机会摆脱了一些 C++ 编码技能的尘埃。
编辑1
由于某种原因,T Monitor<T>::container = ( (typeid(T) == typeid(string)) ? "" : 0);
实际上不适用于 int,仅适用于字符串。
您可以使用专业化:
template<class T> // general case
T Monitor<T>::container = 0;
template<>
std::string Monitor<std::string>::container = "";
或使用默认值
template<class T>
T Monitor<T>::container = T();
我正在尝试实现一个监视器 class 来处理多线程。我必须使用 Visual Studio 2010,所以我没有 c++11。我可以通过创建全局变量来简单地做到这一点,我将跨线程 reading/writing 为每种类型的值一个,并为每个单独的值使用互斥锁,这很简单但更乏味。
所以我想花点时间在 Class 中实现监视器概念。 这项工作在某种程度上是 "done",因为数据类型是 float 或 int,但我想更进一步并实现监视器 class 以支持 C 标准类型和 c++ class es,比如字符串。
我的方法是让静态成员作为跨线程的共享内存工作,这样我唯一要做的就是在两个线程中实例化 class 并且我会正确设置 IPC。
事情是...我必须初始化静态成员,但我无法让它工作,因为字符串和 int-ish 类型(int、float 等...)没有以相同的方式初始化。
这是我尝试做的事情:
template<class T>
class Monitor : protected Mutex {
public:
Monitor(bool Verbose);
~Monitor();
T read(DWORD wait_time=INFINITE);
void write(T value, DWORD wait_time=INFINITE);
//friend void operator= (Monitor& m1, Monitor& m2);
private:
static T container;
};
template<class T>
T Monitor<T>::container = (typeid(T) == typeid(string) ? "" : 0);
如果我只声明了 Monitor<string> pMonitor2(VERB_ON);
或 Monitor<int> pMonitor1(VERB_ON);
,它就可以正常工作。声明两者都会抛出我 error C2440: 'initializing' : cannot convert from 'const char *' to 'int'
.
此外,在 classes 中实现这种进程间通信概念的最佳方法是什么?
到目前为止的完整代码:
monitor.cpp:
#include "monitor.h"
using namespace std;
HANDLE Mutex::hMutex = nullptr;
unsigned int Mutex::counter = 0;
Mutex::Mutex(bool V) {
Verbose = V;
if(hMutex == nullptr) {
if(Verbose) cout << "Creating mutex\n";
hMutex = CreateMutex(
NULL,
FALSE,
(LPCWSTR) "CONTMUTEX");
counter++;
}
else{
if(Verbose) cout <<"Mutex already created\n";
counter++;
}
}
Mutex::~Mutex() {
counter--;
if(counter == 0) {
if(Verbose) cout << "Destroying mutex\n";
CloseHandle(hMutex);
}
else {
if(Verbose) cout << "Awaiting closure of all instances of Mutex\n";
}
}
/*void operator= (Monitor& m1, Monitor& m2) {
m1.write(m2.read());
}*/
monitor.h:
#ifndef MONITOR_INC
#define MONITOR_INC
//#include <vector>
#include <Windows.h>
#include <iostream>
using namespace std;
enum verb{VERB_OFF, VERB_ON};
class Mutex {
public:
Mutex(bool Verbose);
~Mutex();
protected:
bool Verbose;
static HANDLE hMutex;
static unsigned int counter;
};
template<class T>
class Monitor : protected Mutex {
public:
Monitor(bool Verbose);
~Monitor();
T read(DWORD wait_time=INFINITE);
void write(T value, DWORD wait_time=INFINITE);
//friend void operator= (Monitor& m1, Monitor& m2);
private:
static T container;
};
template<class T>
T Monitor<T>::container = (typeid(T) == typeid(string) ? "" : 0);
template<class T>
Monitor<T>::Monitor(bool Verbose) : Mutex(Verbose) {
if(Verbose) cout << "Monitor Constructor\n";
}
template<class T>
Monitor<T>::~Monitor() {
if(Verbose) cout << "Monitor Destructor\n";
}
template<class T>
T Monitor<T>::read(DWORD wait_time) {
T ret_val;
WaitForSingleObject(hMutex, wait_time);
ret_val = container;
ReleaseMutex(hMutex);
return ret_val;
}
template<class T>
void Monitor<T>::write(T value, DWORD wait_time) {
WaitForSingleObject(hMutex, wait_time);
container = value;
ReleaseMutex(hMutex);
}
//void operator= (Monitor& m1, Monitor& m2);
#endif
main.cpp 用于测试:
#include "monitor.h"
#include <string>
#include <sstream>
int main() {
Mutex pMutex1(VERB_ON);
Mutex pMutex2(VERB_ON);
Mutex pMutex3(VERB_ON);
Monitor<int> pMonitor1(VERB_ON);
cout << pMonitor1.read() << "\n";
pMonitor1.write(20);
cout << pMonitor1.read() << "\n";
Monitor<string> pMonitor2(VERB_ON);
cout << pMonitor2.read() << "\n";
pMonitor2.write("TURN DOWN FOR WHAT");
cout << pMonitor2.read() << "\n";
return 0;
}
对于任何不好的做法,我必须事先道歉。自从我上次使用 C++ 编码以来已经过去了大约 8 个月,我借此机会摆脱了一些 C++ 编码技能的尘埃。
编辑1
由于某种原因,T Monitor<T>::container = ( (typeid(T) == typeid(string)) ? "" : 0);
实际上不适用于 int,仅适用于字符串。
您可以使用专业化:
template<class T> // general case
T Monitor<T>::container = 0;
template<>
std::string Monitor<std::string>::container = "";
或使用默认值
template<class T>
T Monitor<T>::container = T();