2013-01-23 98 views
2

我想捕获编译时间传递给模板类型的函数的常量整数。未来的目标是推出我自己的(非常有限的)表达式模板,该模板从非常简单的表达式(编译时间常量int和变量之和)创建表达式,例如:-2 * i + 3 * k。integral_constant和模板参数扣除

我开始很慢,我有以下代码:2

struct Foo { 
    Foo (int i) : i_(i) {} 

    int i_; 
}; 

template <int N> int operator*(std::integral_constant<int, N> i, Foo j) { 
    return N * j.i_; 
} 

int main(void) { 
    std::integral_constant<int, 2> k; 
    int i = k * Foo(3); 
    cout << i << endl; 

    int j = 2 * Foo(3); 
    cout << j << endl; 
} 

模板参数推导失败*美孚(3)。 我已经读过,没有这样的东西作为一个函数的constexpr参数。

有没有办法实现我想要的?

+0

使operaator,构造,并导致“constexpr”。 –

+0

感谢您的回复,我不能使它工作不幸:我修饰了j,运算符和Foo构造函数的定义,我仍然使用gcc-4.6和clang ++获得相同的模板演绎错误。你介意发布一个编译的修改版本吗?另外,一般来说,Foo可能不是一个constexpr,而是我的表达中更通用的术语。 – NickV

+0

我怀疑你可以把2变成一个integral_constant 。你必须至少写我(2)或类似的东西,我是一个宏。表达式模板中有什么用int_cst类型的成员int来存储数字2.不完全一样... –

回答

3

你可以做到没有模板。这个答案或多或少的扩张@ MooingDuck的建议转化为具体的代码,你可能会发现更容易理解:

#include <type_traits> 

using namespace std; 

struct Foo { 
    constexpr Foo (int i) : i_(i) {} 
    int i_; 
}; 

constexpr int operator*(int i, Foo j) { 
    return i * j.i_; 
} 

int main(void) { 
    integral_constant<int, 2> k; 

    constexpr int i = k * Foo(3); 
    static_assert(i == 6, "Error!"); 

    constexpr int j = 2 * Foo(3); 
    static_assert(j == 6, "Error!"); 
} 
+1

http://stacked-crooked.com/view?id=90398ee0c8dd684a0cf53f6fb34dbe7e哦,嘿,'integral_constant '有一个隐式转换为'int'?我不知道!这是新的吗?这段代码很好。 –

+2

@MooingDuck:它在C++标准的第20.9.3节中有规定。 'integral_constant <>'有一个'constexpr'转换运算符到底层类型(是的,运算符没有标记为'explicit') –