Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c++;整数的力量,模板元编程_C++_Templates_C++11_Template Meta Programming - Fatal编程技术网

C++ c++;整数的力量,模板元编程

C++ c++;整数的力量,模板元编程,c++,templates,c++11,template-meta-programming,C++,Templates,C++11,Template Meta Programming,我想做一个返回整数幂的函数。 请阅读中的fmuecke解决方案 然而,我想把他的解推广到任意类型的T。 由于c++11有constexpr,我想这是可能的 天真地,我试过这样的方法 template<class T, int N> inline constexpr T pow(const T x){ return pow<N-1>(x) * x; } template<class T> inline constexpr T pow<T, 1&g

我想做一个返回整数幂的函数。 请阅读中的fmuecke解决方案

然而,我想把他的解推广到任意类型的T。 由于c++11有constexpr,我想这是可能的

天真地,我试过这样的方法

template<class T, int N>
inline constexpr T pow(const T x){
    return pow<N-1>(x) * x;
}
template<class T>
inline constexpr T pow<T, 1>(const T x){
    return x;
}
template<class T>
inline constexpr T pow<T, 0>(const T x){
    return 1;
}
模板
内联电容器输出功率(电容器x){
返回功率(x)*x;
}
模板
内联电容器输出功率(电容器x){
返回x;
}
模板
内联电容器输出功率(电容器x){
返回1;
}
实际上,这种方法失败了,因为不允许对函数模板进行部分专门化

还有一个问题。我听说是否在编译时对constexpr函数求值取决于编译器。 对于一般类型,如何强制它进行计算。
我从某个地方读到,整数常量的一个最简单的技巧是将其包装在std::integral_const::value中

当您发现自己需要部分专门化一个函数模板时(注意,这并不意味着在这种情况下您需要,如图所示),您可以求助于重载(参见本答案末尾的最后一次更新),或者,如果不可能,将该函数模板包装到一个类模板中,并具有一个静态,非模板成员函数替换原始函数模板(及其专门化):

更新:

作为进一步的说明,请记住,即使您可以专门化函数模板(例如,使用显式专门化而不是部分专门化),这样做通常不是一个好主意,因为函数模板专门化通常不会像预期的那样进行

大多数看起来需要函数模板专门化的情况实际上都可以通过重载来实现,这种重载由众所周知的技术(如标记分派提供支持)。Potatoswatter提出了一个例子,指出在这种情况下可以使用
std::integral_constant

template<class T>
inline constexpr T pow(const T x, std::integral_constant<T, 0>){
    return 1;
}

template<class T, int N>
inline constexpr T pow(const T x, std::integral_constant<T, N>){
    return pow(x, std::integral_constant<T, N-1>()) * x;
}

template<int N, class T>
inline constexpr T pow(const T x)
{
    return pow(x, std::integral_constant<T, N>());
}
模板
内联常数表达式T pow(常数T x,标准::积分常数){
返回1;
}
模板
内联常数表达式T pow(常数T x,标准::积分常数){
返回功率(x,std::integral_constant())*x;
}
模板
内联电容器输出功率(电容器x)
{
返回功率(x,std::积分常数();
}

然而,所有这些关于“如何解决似乎需要函数模板部分专门化的问题”的指导原则在真正需要时都应该考虑。在这个具体的例子中,正如DyP在他的回答中所示,它们不是。使用递归的解决方案:

#include <iostream>

template<class T>
inline constexpr T pow(const T base, unsigned const exponent)
{
    // (parentheses not required in next line)
    return (exponent == 0) ? 1 : (base * pow(base, exponent-1));
}

int main()
{
    std::cout << "pow(2, 4): " << pow(2, 4) << std::endl;
    std::cout << "pow(5, 0): " << pow(5, 0) << std::endl;
}


如果您否决投票,请留下评论,以便我可以改进我的答案。

这里有一个单一功能的解决方案:

template <int N, class T> 
constexpr T pow(const T& x) 
{
    return N > 1 ? x*pow<(N-1)*(N > 1)>(x) 
                 : N < 0 ? T(1)/pow<(-N)*(N < 0)>(x) 
                         : N == 1 ? x 
                                  : T(1);
}
模板
康斯特普特电力公司(康斯特普特电力公司)
{
返回N>1?x*功率1)>(x)
:N<0?T(1)/pow(x)
:N==1?x
:T(1);
}

以下是一个简单的解决方案:

#include<bits/stdc++.h>
using namespace std;

template<int N, int M>
struct Pow
{
    enum { res = N * Pow<N,M-1>::res};
};


template<int N>
struct Pow<N,0>
{
    enum {res = 1};
};
int main()
{
    cout<<Pow<2,3>::res<<"\n";
}
#包括
使用名称空间std;
模板
结构功率
{
枚举{res=N*Pow::res};
};
模板
结构功率
{
枚举{res=1};
};
int main()
{

cout@B不,不是,但为什么需要模板元编程方法?你也可以在元编程中使用
constepr
函数(及其结果)。@Bааћћ说真的,谁在乎呢?“你确定你用蓝色锤子钉这个钉子吗?”“这个词让我感到困惑。”B.Y.Y.Y.Y.Y.Y.Y.Yuang:很抱歉混淆了它的标题。也许它应该被修改成int的编译时间。如果使用它,它会更好。+ 1我完全钦佩你,你似乎知道C++的每一点。读你的答案总是很高兴。Sungmin:没关系,DyP的答案显示了正确的方法。对于这个特殊的问题,我的主要是一个更一般的指导方针situations@0x499602D2:的确,它(7.1.5/2)确实需要
constepr
inline
吗?@0x499602D2:不需要
#include <iostream>

template<class T>
inline constexpr T pow(const T base, unsigned const exponent)
{
    // (parentheses not required in next line)
    return (exponent == 0) ? 1 : (base * pow(base, exponent-1));
}

int main()
{
    std::cout << "pow(2, 4): " << pow(2, 4) << std::endl;
    std::cout << "pow(5, 0): " << pow(5, 0) << std::endl;
}
template<class T>
inline constexpr T pow(const T base, unsigned const exponent)
{
    // (parentheses not required in next line)
    return (exponent == 0)     ? 1 :
           (exponent % 2 == 0) ? pow(base, exponent/2)*pow(base, exponent/2) :
           base * pow(base, (exponent-1)/2) * pow(base, (exponent-1)/2);
}
std::cout << std::integral_constant<int, pow(2, 4)>::value << std::endl;
#include <iostream>
#include <type_traits>

// insert a constexpr `pow` implementation, e.g. the one from above

template < typename T, T base, unsigned exponent >
using pow_ = std::integral_constant < T, pow(base, exponent) >;

// macro == error prone, you have been warned
#define POW(BASE, EXPONENT) (pow_ < decltype(BASE), BASE, EXPONENT > :: value)

int main()
{
    std::cout << "pow(2, 4): " << pow_<int, 2, 4>::value << std::endl;
    std::cout << "pow(2, 4): " << POW(2, 4) << std::endl;
}
template <int N, class T> 
constexpr T pow(const T& x) 
{
    return N > 1 ? x*pow<(N-1)*(N > 1)>(x) 
                 : N < 0 ? T(1)/pow<(-N)*(N < 0)>(x) 
                         : N == 1 ? x 
                                  : T(1);
}
#include<bits/stdc++.h>
using namespace std;

template<int N, int M>
struct Pow
{
    enum { res = N * Pow<N,M-1>::res};
};


template<int N>
struct Pow<N,0>
{
    enum {res = 1};
};
int main()
{
    cout<<Pow<2,3>::res<<"\n";
}