我正在尝试使用#define创建一个允许我按需创建新类的宏。这是我的代码:
#pragma once
#include "PDDefFileReader.h"
#define SET_LANG( lang ) *( new std::string( lang ) )
#define LANG( cName, lName )
class cName
{
public:
cName()
{
_langName = SET_LANG( lName ); <- HERE !!!!
_reader = new PDDefFileReader( _langName );
}
~cName(){}
std::string Str(){ return _langName; }
private:
PDDefFileReader* _reader;
std::string _langName;
};
所以我想知道如果我想将define的“lName”参数作为std :: string对象,我应该怎么做。现在(在“HERE !!!!”行)我收到错误:
Error: Identifier "lName" is undefined
知道我想做什么是可能的吗?
为了给你一些背景知识,我正在做一个自定义的多语言阅读器。所以我可以通过做类似的事情来简单地定义新语言:
LANG( Cpp, "cpp" )
LANG( Perl, "pl" )
谢谢!
答案 0 :(得分:5)
您的宏为空,默认情况下它不会继续到下一行,除非您在最后使用\
,例如
#define #define LANG( cName, lName ) \
class cName \
{ \
...
答案 1 :(得分:0)
我很想用模板来解决你的问题 - 这就是他们真正想要的。
不幸的是,坏消息是模板参数虽然可以占用大多数类型但根本不会处理char*
或char[]
。所以:
template <char* TLang>
class
...
不幸的是,在大多数重要的用例中都是非法的C ++,请参阅this question及其各自的答案。
但是,您可以使用模板来实现policy based design这是现代C ++设计的第一章(第二章?),并在该链接中进行了相当好的描述。这个想法是你继承了不同的(模板提供的)类来实现不同的“策略”。
这实现了与您的目标相同的效果。在编译时为每个实例化的值生成模板,所以如果我有一个类:
cName<CppPolicy> CppName;
然后这会生成一个CppName
实例,它是cName
类的类,它继承了CppPolicy
的某些策略功能。
如果我不得不猜测,我会说你将根据该字符串的值决定如何为给定的语言做什么 - 在这种情况下,基于策略的设计可能是你想看的东西。这具有避免涉及字符串比较的大if
语句的附加优点。
但是,如果您只是在寻找字符串常量,为什么不简单地使用它们,或者在注释中建议为每种语言的实例提供常量?
实际上,在同一个模块中实际使用LANG
两次会产生编译错误,因为你将有两个名为cName
的类。