您在C ++中看到过哪些最酷的元编程实例?

时间:2022-09-20 19:36:51

This question exists because it has historical significance, but it is not considered a good, on-topic question for this site, so please do not use it as evidence that you can ask similar questions here.

这个问题之所以存在,是因为它具有历史意义,但对于本网站而言,它不被认为是一个好的,主题上的问题,因此请不要将其作为您可以在此处提出类似问题的证据。

More info: https://*.com/faq

更多信息:https://*.com/faq


What are the coolest examples of metaprogramming that you've seen in C++?
What are some practical uses of metaprogramming that you've seen in C++?

您在C ++中看到过哪些最酷的元编程实例?您在C ++中看到的元编程有哪些实际用途?

10 个解决方案

#1


23  

Personally, I think Boost.Spirit is a pretty amazing example of meta-programming. It's a complete parser generator that lets you express grammars using C++ syntax.

就个人而言,我认为Boost.Spirit是一个非常神奇的元编程实例。它是一个完整的解析器生成器,可以让您使用C ++语法表达语法。

#2


19  

The most practical use of meta programming is turning a runtime error into a compile time error.

元编程的最实际用途是将运行时错误转换为编译时错误。

Example: Lets call the interface IFoo. One of my programs dealt with a COM object that had multiple paths to IFoo (very complicated inheritance hierarchy). Unfortunately the underlying COM object implementation didn't realize they had multiple paths to IFoo. They assumed it was always the left most one. So inside their code, the following pattern was very common

示例:让我们调用接口IFoo。我的一个程序处理的是一个COM对象,它有多条到IFoo的路径(非常复杂的继承层次结构)。不幸的是,底层的COM对象实现没有意识到他们有多条路径到IFoo。他们认为它总是最左边的一个。所以在他们的代码中,以下模式非常常见

   void SomeMethod(IFoo* pFoo) {
        CFooImpl *p = (CFooImpl)pFoo;
   }

The second IFoo though caused the resulting "p" pointer to be completely invalid (multiple inheritance is dangerous).

第二个IFoo虽然导致生成的“p”指针完全无效(多重继承是危险的)。

The long term solution was to have the COM object owner fix this issue. Short term though I needed to make sure that I always returned the correct IFoo. I could guarantee that I had the appropriate IFoo by using a QI and avoiding any implicit casts to IFoo. So I created a new CComPtr<> implementation and added the following override to the equal method.

长期解决方案是让COM对象所有者解决此问题。短期虽然我需要确保我总是返回正确的IFoo。我可以通过使用QI并避免对IFoo进行任何隐式转换来保证我拥有适当的IFoo。所以我创建了一个新的CComPtr <>实现,并将以下覆盖添加到equal方法中。

template <typename T>
CComPtr<T>& operator=(const T* pT)  { 
// CComPTr Assign logic
}
template <>
CComPtr<IFoo> operator=<IFoo>(const IFoo* pT) {
  COMPILE_ERROR();
}

This quickly revealed every single place I implicitly casted to IFoo.

这很快就揭示了我隐含地投入到IFoo的每一个地方。

#3


12  

Blitz++ does some impressive things with templates (for instance, a single readable line of code can be turned into a set of loops over a multidimensional array, automatically optimized for the best traversal order).

Blitz ++使用模板做了一些令人印象深刻的事情(例如,单个可读代码行可以转换为多维数组上的一组循环,自动针对最佳遍历顺序进行优化)。

#4


12  

Not of practical usage (except maybe for compiler testing), but metatrace is a Whitted-Style (i.e. recursive and deterministic) ray tracer which generates images like those at compilation time:

不是实际用法(除了可能用于编译器测试),但metatrace是一个Whitted-Style(即递归和确定性)光线跟踪器,它可以生成像编译时那样的图像:

您在C ++中看到过哪些最酷的元编程实例?

Some more complex parts of the code can be seen in fixp.hh, which has an implementation of fixed-point sqrt using the Heron method, or sphere.hh which shows ray/sphere-intersection calculation.

在fixp.hh中可以看到代码的一些更复杂的部分,它使用Heron方法实现定点sqrt,或者使用sphere.hh显示光线/球体交叉计算。

#5


8  

Loki written by Andrei Alexandrescu

Loki由Andrei Alexandrescu撰写

#6


7  

Coolest metaprogramming example: tricking the compiler into computing a list of prime numbers. Not very practical, but impressive.

最酷的元编程示例:欺骗编译器计算素数列表。不太实用,但令人印象深刻。

One practical use is compile-time assert statements, i.e. causing a compile error if a Boolean condition does not hold.

一个实际用途是编译时断言语句,即如果布尔条件不成立则导致编译错误。

#7


4  

I would have to say Boost.Lambda, Boost.Function, and Boost.Bind and the way that they all work seamlessly together. They provide a really slick interface and make functional programming about as easy as possible in a language that wasn't really built for it.

我不得不说Boost.Lambda,Boost.Function和Boost.Bind以及它们无缝地协同工作的方式。它们提供了一个非常灵活的界面,并使用一种非真正为它构建的语言尽可能简单地进行函数式编程。

#8


2  

luabind is a pretty cool practical example, quite a nice binding dsl for binding C++ classes to lua

luabind是一个非常酷的实例,非常好用于将C ++类绑定到lua的绑定dsl

#9


1  

BOOST_FOREACH

Static assertion (boosts version here)

静态断言(在这里提升版本)

#10


0  

I posed a question not to long ago: C++ Runtime Knowledge of Classes and the answer I got back from a * user "Denice" was a URL to a website Meatspace: C++ runtime class registration.

我不久前提出了一个问题:C ++运行时类的知识和我从*用户“Denice”返回的答案是网站Meatspace的URL:C ++运行时类注册。

I think that is a really cool way to use templates and instantiate objects that are all derived from a base class, so that when I have 10 C++ files, they can all just add the AUTO_REGISTER_BASE() at the bottom, and when everything is all done and linked, only those classes/files that made it would be registered, so at runtime you can switch between the different classes that are available, and those that are not available are not registered and thus can't accidently be called.

我认为这是一种非常酷的方式来使用模板和实例化所有从基类派生的对象,所以当我有10个C ++文件时,他们都可以在底部添加AUTO_REGISTER_BASE(),当一切都是完成并链接,只有那些使它成功的类/文件才会被注册,所以在运行时你可以在可用的不同类之间切换,那些不可用的类没有注册,因此无法被意外调用。

There are many different OS dependant ways to do event notification (select(), kqueue(), /dev/epoll, Solaris has it's own thing, poll()), and I needed a way to have all of the class files exist in the directory, but depending on what OS the Makefile was run, it would only compile certain ones. I needed a way to know at runtime which ones were available, and have a way for the programmer using the library to select their preference, however if it was unavailable to just use the one that made the most logical sense for the platform (they each have weights assigned to them).

有很多不同的操作系统相关的方法来做事件通知(select(),kqueue(),/ dev / epoll,Solaris有它自己的东西,poll()),我需要一种方法来存在所有的类文件该目录,但根据运行Makefile的操作系统,它只会编译某些。我需要一种方法在运行时知道哪些是可用的,并且让程序员使用库来选择他们的偏好,但是如果它不可用于仅使用对平台最有逻辑意义的那个(他们每个有权重分配给他们)。

The code above helped me accomplish this goal, with some hefty modifications, but it helped me none-the-less!

上面的代码帮助我完成了这个目标,进行了一些重大的修改,但它帮助了我!

#1


23  

Personally, I think Boost.Spirit is a pretty amazing example of meta-programming. It's a complete parser generator that lets you express grammars using C++ syntax.

就个人而言,我认为Boost.Spirit是一个非常神奇的元编程实例。它是一个完整的解析器生成器,可以让您使用C ++语法表达语法。

#2


19  

The most practical use of meta programming is turning a runtime error into a compile time error.

元编程的最实际用途是将运行时错误转换为编译时错误。

Example: Lets call the interface IFoo. One of my programs dealt with a COM object that had multiple paths to IFoo (very complicated inheritance hierarchy). Unfortunately the underlying COM object implementation didn't realize they had multiple paths to IFoo. They assumed it was always the left most one. So inside their code, the following pattern was very common

示例:让我们调用接口IFoo。我的一个程序处理的是一个COM对象,它有多条到IFoo的路径(非常复杂的继承层次结构)。不幸的是,底层的COM对象实现没有意识到他们有多条路径到IFoo。他们认为它总是最左边的一个。所以在他们的代码中,以下模式非常常见

   void SomeMethod(IFoo* pFoo) {
        CFooImpl *p = (CFooImpl)pFoo;
   }

The second IFoo though caused the resulting "p" pointer to be completely invalid (multiple inheritance is dangerous).

第二个IFoo虽然导致生成的“p”指针完全无效(多重继承是危险的)。

The long term solution was to have the COM object owner fix this issue. Short term though I needed to make sure that I always returned the correct IFoo. I could guarantee that I had the appropriate IFoo by using a QI and avoiding any implicit casts to IFoo. So I created a new CComPtr<> implementation and added the following override to the equal method.

长期解决方案是让COM对象所有者解决此问题。短期虽然我需要确保我总是返回正确的IFoo。我可以通过使用QI并避免对IFoo进行任何隐式转换来保证我拥有适当的IFoo。所以我创建了一个新的CComPtr <>实现,并将以下覆盖添加到equal方法中。

template <typename T>
CComPtr<T>& operator=(const T* pT)  { 
// CComPTr Assign logic
}
template <>
CComPtr<IFoo> operator=<IFoo>(const IFoo* pT) {
  COMPILE_ERROR();
}

This quickly revealed every single place I implicitly casted to IFoo.

这很快就揭示了我隐含地投入到IFoo的每一个地方。

#3


12  

Blitz++ does some impressive things with templates (for instance, a single readable line of code can be turned into a set of loops over a multidimensional array, automatically optimized for the best traversal order).

Blitz ++使用模板做了一些令人印象深刻的事情(例如,单个可读代码行可以转换为多维数组上的一组循环,自动针对最佳遍历顺序进行优化)。

#4


12  

Not of practical usage (except maybe for compiler testing), but metatrace is a Whitted-Style (i.e. recursive and deterministic) ray tracer which generates images like those at compilation time:

不是实际用法(除了可能用于编译器测试),但metatrace是一个Whitted-Style(即递归和确定性)光线跟踪器,它可以生成像编译时那样的图像:

您在C ++中看到过哪些最酷的元编程实例?

Some more complex parts of the code can be seen in fixp.hh, which has an implementation of fixed-point sqrt using the Heron method, or sphere.hh which shows ray/sphere-intersection calculation.

在fixp.hh中可以看到代码的一些更复杂的部分,它使用Heron方法实现定点sqrt,或者使用sphere.hh显示光线/球体交叉计算。

#5


8  

Loki written by Andrei Alexandrescu

Loki由Andrei Alexandrescu撰写

#6


7  

Coolest metaprogramming example: tricking the compiler into computing a list of prime numbers. Not very practical, but impressive.

最酷的元编程示例:欺骗编译器计算素数列表。不太实用,但令人印象深刻。

One practical use is compile-time assert statements, i.e. causing a compile error if a Boolean condition does not hold.

一个实际用途是编译时断言语句,即如果布尔条件不成立则导致编译错误。

#7


4  

I would have to say Boost.Lambda, Boost.Function, and Boost.Bind and the way that they all work seamlessly together. They provide a really slick interface and make functional programming about as easy as possible in a language that wasn't really built for it.

我不得不说Boost.Lambda,Boost.Function和Boost.Bind以及它们无缝地协同工作的方式。它们提供了一个非常灵活的界面,并使用一种非真正为它构建的语言尽可能简单地进行函数式编程。

#8


2  

luabind is a pretty cool practical example, quite a nice binding dsl for binding C++ classes to lua

luabind是一个非常酷的实例,非常好用于将C ++类绑定到lua的绑定dsl

#9


1  

BOOST_FOREACH

Static assertion (boosts version here)

静态断言(在这里提升版本)

#10


0  

I posed a question not to long ago: C++ Runtime Knowledge of Classes and the answer I got back from a * user "Denice" was a URL to a website Meatspace: C++ runtime class registration.

我不久前提出了一个问题:C ++运行时类的知识和我从*用户“Denice”返回的答案是网站Meatspace的URL:C ++运行时类注册。

I think that is a really cool way to use templates and instantiate objects that are all derived from a base class, so that when I have 10 C++ files, they can all just add the AUTO_REGISTER_BASE() at the bottom, and when everything is all done and linked, only those classes/files that made it would be registered, so at runtime you can switch between the different classes that are available, and those that are not available are not registered and thus can't accidently be called.

我认为这是一种非常酷的方式来使用模板和实例化所有从基类派生的对象,所以当我有10个C ++文件时,他们都可以在底部添加AUTO_REGISTER_BASE(),当一切都是完成并链接,只有那些使它成功的类/文件才会被注册,所以在运行时你可以在可用的不同类之间切换,那些不可用的类没有注册,因此无法被意外调用。

There are many different OS dependant ways to do event notification (select(), kqueue(), /dev/epoll, Solaris has it's own thing, poll()), and I needed a way to have all of the class files exist in the directory, but depending on what OS the Makefile was run, it would only compile certain ones. I needed a way to know at runtime which ones were available, and have a way for the programmer using the library to select their preference, however if it was unavailable to just use the one that made the most logical sense for the platform (they each have weights assigned to them).

有很多不同的操作系统相关的方法来做事件通知(select(),kqueue(),/ dev / epoll,Solaris有它自己的东西,poll()),我需要一种方法来存在所有的类文件该目录,但根据运行Makefile的操作系统,它只会编译某些。我需要一种方法在运行时知道哪些是可用的,并且让程序员使用库来选择他们的偏好,但是如果它不可用于仅使用对平台最有逻辑意义的那个(他们每个有权重分配给他们)。

The code above helped me accomplish this goal, with some hefty modifications, but it helped me none-the-less!

上面的代码帮助我完成了这个目标,进行了一些重大的修改,但它帮助了我!