Inheritance instead of typedef
问题是,当然,c++模板元编程是基于模板的,因此,当你在深度嵌套的模板结构中遇到编译器错误时,你必须在10行错误消息中挖掘。我甚至养成了在文本编辑器中复制/粘贴消息的习惯,然后缩进消息以获得一些结构,直到我了解实际发生的情况,这为跟踪错误本身增加了一些工作。
据我所知,问题主要是由于编译器及其输出typedef的方式造成的(还有其他问题,如嵌套深度,但这并不是编译器的错)。即将到来的C++0x宣布了可变模板或类型推断(自动)等很酷的功能,但我真的希望有更好的错误消息来引导。使用模板元编程可能会很痛苦,我确实想知道当更多的人真正开始使用它们时,这会变成什么样子。
typedef partition<AnyType> MyArg;
struct MyArg2: partition<AnyType> {};
然而,这涉及到另一个问题。为了确保我没有做任何愚蠢的事情,我经常这样编写我的模板函数/类:
template <class T> T& get(partition<T>&);
CRTP
template <class Derived, class T> partition;
template <class Derived, class T> T& get(partition<Derived,T>&);
这允许知道在编译器使用公共继承之前用于调用方法的“真实”类型。应该注意的是,这降低了调用此特定函数的机会,因为编译器必须执行转换,但到目前为止,我从未注意到任何问题。
SFINAE
.
struct partition_tag {};
template <class T> struct partition { typedef partition_tag tag; ... };
template <class T>
typename boost::enable_if<
boost::same_type<
typename T::tag,
partition_tag
>,
T&
>::type
get(T&)
{
...
}
不过,它需要更多的键入,特别是如果在不同的地方声明和定义函数/方法(如果我不费心,我的接口很快就会变得混乱)。然而,当涉及到类时,由于没有执行类型转换,它确实变得更加复杂:
template <class T>
class MyClass { /* stuff */ };
// Use of boost::enable_if
template <class T, class Enable = void>
class MyClass { /* empty */ };
template <class T>
class MyClass <
T,
boost::enable_if<
boost::same_type<
typename T::tag,
partition_tag
>
>
>
{
/* useful stuff here */
};
// OR use of the static assert
template <class T>
class MyClass
{
BOOST_STATIC_ASSERT((/*this comparison of tags...*/));
};
你如何限制方法/函数的范围,或者以其他方式控制提供给它们(以及类)的参数的类型?
编辑:
BOOST_MPL_ASSERT_MSG
它可能对代码自我文档和更好的错误输出都有很大帮助。