是否可以编写一个模板来改变行为,具体取决于是否在类上定义了某个成员函数?
这是我想写的一个简单例子:
template<class T>
std::string optionalToString(T* obj)
{
if (FUNCTION_EXISTS(T->toString))
return obj->toString();
else
return "toString not defined";
}
Run Code Online (Sandbox Code Playgroud)
所以,如果class T
已经toString()
确定的话,就使用它; 否则,它没有.我不知道怎么做的神奇部分是"FUNCTION_EXISTS"部分.
这是一个有点离奇的问题.我的目标是理解语言设计决策并确定C++中反射的可能性.
为什么C++语言委员会不会在语言中实现反思?对于不在虚拟机上运行的语言(如java),反射是否太难?
如果要实现C++的反射,那么挑战是什么?
我想反射的使用是众所周知的:编辑器可以更容易编写,程序代码更小,可以为单元测试生成模拟等等.但是,如果你也可以对反射的使用发表评论,那就太棒了.
我有一个文件:Base.h
class Base;
class DerivedA : public Base;
class DerivedB : public Base;
/*etc...*/
Run Code Online (Sandbox Code Playgroud)
和另一个文件:BaseFactory.h
#include "Base.h"
class BaseFactory
{
public:
BaseFactory(const string &sClassName){msClassName = sClassName;};
Base * Create()
{
if(msClassName == "DerivedA")
{
return new DerivedA();
}
else if(msClassName == "DerivedB")
{
return new DerivedB();
}
else if(/*etc...*/)
{
/*etc...*/
}
};
private:
string msClassName;
};
/*etc.*/
Run Code Online (Sandbox Code Playgroud)
有没有办法以某种方式将此字符串转换为实际类型(类),以便BaseFactory不必知道所有可能的Derived类,并为每个类都有if()?我可以用这个字符串生成一个类吗?
我认为这可以通过Reflection在C#中完成.C++中有类似的东西吗?
我现在要用c ++ 11编写大项目.
我正在寻找一些好的c ++ 11/c ++反射库,我发现了几个不同的库,但是大多数库在过去几年都没有更新,或者它们的功能非常有限.
你能告诉我是否有一个非常好的c ++ 1/c ++库用于反射?(我希望有静态和动态反射,尽可能多地了解方法,类等信息,可以动态添加和访问方法等)
或许c ++ 11提供了一些额外的功能,有助于更好地设计反射库,我应该自己编写吗?(虽然我没有找到有关它的信息.)
Herb Sutter提出了一个简单的实现make_unique()
:http://herbsutter.com/gotw/_102/
这里是:
template<typename T, typename ...Args>
std::unique_ptr<T> make_unique( Args&& ...args )
{
return std::unique_ptr<T>( new T( std::forward<Args>(args)... ) );
}
Run Code Online (Sandbox Code Playgroud)
我的问题是可变参数模板还不是VS2012的一部分,所以我不能按原样使用这个代码.
有没有一种可维护的方法在VS2012中写这个不会涉及使用不同的args计数复制粘贴相同的函数?
在C++中,有没有办法从它的指针中获取函数签名/名称?
void test(float data) {}
cout << typeid(&test).name();
Run Code Online (Sandbox Code Playgroud)
我想使用这些数据进行日志记录.
假设我有一个有100个孩子的基类:
class Base {
virtual void feed();
...
};
class Child1 : public Base {
void feed(); //specific procedure for feeding Child1
...
};
...
class Child100 : public Base {
void feed(); //specific procedure for feeding Child100
...
};
Run Code Online (Sandbox Code Playgroud)
在运行时,我想读取一个文件,其中包含要创建和提供的子项.假设我已经读过文件,字符串"names"的向量包含子类的名称(即Child1,Child4,Child99).现在,我将遍历这些字符串,创建特定子项的实例,并使用其特定的提供过程来提供它:
vector<Base *> children;
for (vector<string>::iterator it = names.begin(); it != names.end(); ++it) {
Base * child = convert_string_to_instance(*it)
child->feed()
children.push_back(child);
}
Run Code Online (Sandbox Code Playgroud)
我如何创建函数convert_string_to_instance(),这样如果它接受字符串"Child1"它返回一个"new Child1",如果字符串参数是"Child4"它返回一个"new Child4",等等
<class C *> convert_string_to_instance(string inName) {
// magic happens
return new C; // C = …
Run Code Online (Sandbox Code Playgroud) 两个stackoverflow 答案建议使用fusion adapt_struct迭代结构字段的方法.这种方法看起来不错.但是,如何迭代到一个本身就是结构的字段?
根据之前的答案,我想出了下面的代码.问题出在代码无法编译的"#if 0"子句中.作为替代解决方案,我创建了"decode()"函数来获取指向目标参数的void指针.这有效,但在编译时丢失了类型信息.有更好的解决方案吗?
struct Foo_s { int i; };
BOOST_FUSION_ADAPT_STRUCT( Foo_s, (int, i) )
struct Bar_s { int v; Foo_s w; };
BOOST_FUSION_ADAPT_STRUCT( Bar_s, (int, v) (Foo_s, w) )
struct AppendToTextBox {
template <typename T> void operator()(T& t) const {
int status = 0;
const char *realname = abi::__cxa_demangle(typeid(t).name(), 0, 0, &status);
printf(" typename: %s value: %s realname: %s\n", typeid(t).name(),
boost::lexical_cast<std::string>(t).c_str(), realname);
std::string rn(realname);
if ( rn.rfind("_s") == rn.size()-2 ) {
#if 0 /* this can …
Run Code Online (Sandbox Code Playgroud) c++ reflection introspection boost-fusion template-meta-programming
如何从字符串中调用C++函数?
而不是这样做,直接从字符串调用方法:
void callfunction(const char* callthis, int []params)
{
if (callthis == "callA")
{
callA();
}
else if (callthis == "callB")
{
callB(params[0], params[1]);
}
else if (callthis == "callC")
{
callC(params[0]);
}
}
Run Code Online (Sandbox Code Playgroud)
在C#中我们使用typeof()然后从那里获取方法信息和调用...我们可以在C++中使用什么?
c++ ×9
reflection ×4
c++11 ×2
templates ×2
boost-fusion ×1
c ×1
c# ×1
dynamic ×1
factory ×1
function ×1
inheritance ×1
instance ×1
new-operator ×1
sfinae ×1
string ×1
unique-ptr ×1