C++ 检查模板中的负片?

C++ 检查模板中的负片?,c++,c++11,template-meta-programming,C++,C++11,Template Meta Programming,这不是一个很重要的问题,但它一直困扰着我一段时间。基本上,我已经开始学习用C++中的模板学习元编程,因为它看起来很有趣。在学习过程中,我发现了一个简单的阶乘示例: template <int n> struct factorial { enum { value = factorial<n - 1>::value }; }; template <> struct factorial<0> { enum { value = 1 };

这不是一个很重要的问题,但它一直困扰着我一段时间。基本上,我已经开始学习用C++中的模板学习元编程,因为它看起来很有趣。在学习过程中,我发现了一个简单的阶乘示例:

template <int n>
struct factorial {
    enum { value = factorial<n - 1>::value };
};

template <>
struct factorial<0> {
    enum { value = 1 };
};
模板
结构阶乘{
枚举{value=factorial::value};
};
模板
结构阶乘{
枚举{值=1};
};
从这一点上,我想添加我自己的部分,这部分内容摘自我的一个朋友正在学习的介绍课程中的一个极其基本的程序作业。如果给定的数字是负数,我需要添加的唯一附加部分是打印-1

这就是我遇到麻烦的地方。我试过几种不同的方法,但很快就失控了,而且大多数时候错误都很令人困惑。在这一点上,我想知道是否有可能做这样简单的事情。起初,我认为这很容易:

template <int n>
struct factorial {
    enum { value = (n < 0) ? -1 : factorial<n>::value };
};

template <>
struct factorial<0> {
    enum { value = 1 };
};
模板
结构阶乘{
枚举{value=(n<0)?-1:阶乘::值};
};
模板
结构阶乘{
枚举{值=1};
};
但这会在编译器中运行,直到给定负数时退出。我还尝试了几种不同的方法,包括多制作2-6个函数和临时typedef等,结果导致了一大堆错误

简单地说:如果给定的数字为负数,有没有办法有条件地执行另一个模板?例如,类似这样的内容:

template <int n>
struct factorial {
    enum { value = factorial<n, negative<n>::value>::value };
};

template <>
struct factorial<0> {
    enum { value = 1 };
};

template <>
struct factorial<(n < 0)> {
    enum { value = -1 };
};
namespace detail {
    template <int n, bool isNegative>
    struct factorial_impl {
        enum { value = n * factorial_impl<n - 1, isNegative>::value };
    };

    template <int n>
    struct factorial_impl<n, true> {
        enum { value = -1 };
    };

    template <>
    struct factorial_impl<0, false> {
        enum { value = 1 };
    };
}

template <int n>
struct factorial {
    enum { value = detail::factorial_impl<n, n < 0>::value };
};
模板
结构阶乘{
枚举{value=factorial::value};
};
模板
结构阶乘{
枚举{值=1};
};
模板
结构阶乘{
枚举{value=-1};
};

例如,如下所示:

template <int n>
struct factorial {
    enum { value = factorial<n, negative<n>::value>::value };
};

template <>
struct factorial<0> {
    enum { value = 1 };
};

template <>
struct factorial<(n < 0)> {
    enum { value = -1 };
};
namespace detail {
    template <int n, bool isNegative>
    struct factorial_impl {
        enum { value = n * factorial_impl<n - 1, isNegative>::value };
    };

    template <int n>
    struct factorial_impl<n, true> {
        enum { value = -1 };
    };

    template <>
    struct factorial_impl<0, false> {
        enum { value = 1 };
    };
}

template <int n>
struct factorial {
    enum { value = detail::factorial_impl<n, n < 0>::value };
};
名称空间详细信息{
模板
结构阶乘{
枚举{value=n*阶乘_impl::value};
};
模板
结构阶乘{
枚举{value=-1};
};
模板
结构阶乘{
枚举{值=1};
};
}
模板
结构阶乘{
枚举{value=detail::factorial_impl::value};
};

你不“执行”模板,它们不是可执行代码。@Jonathan:把它们看作是执行你的模板以生成将放入可执行文件中的函数的编译器,这并不是不合理的。@Hurkyl,我认为这没有帮助,因为它可以给人一种误导的印象,即与模板一样,命令式编程风格可以与“正常”C++代码一起使用。模板元编程需要一种非常不同的方法,最好避免与“执行”或“运行”任何内容相关的任何混淆。例如,OP问题中的
?:
运算符的两个分支都被“执行”,因为编译器实例化了这两个分支中的模板。@Jonathan:如果你不能区分执行元程序以生成程序组件的编译器,我知道这是多么没有帮助,CPU执行由链接器创建的二进制文件。但了解这一区别确实很有帮助。顺便说一句,声明式风格在元编程中确实适用,只要您适应了所有变量都是常量的怪癖。当然,更常见的想法是以函数式的方式进行元编程。使用
unsigned
而不是
int
,这不再是一个问题。这相当快!我发誓我以前也试过类似的方法。我必须将它与我以前的一些迭代进行比较。谢谢你的回答!