c ++中的元最小值

时间:2014-11-27 17:52:23

标签: c++ template-meta-programming

我正在尝试使用模板元编程在c ++中进行最小化查找:

template<int first,int...a>
struct min
{
    static const int value= sizeof...(a) && first>min<a...>::value ? 
                             min<a...>::value : 
                             first;
};

将被称为:

static const int eleven = min<42,97,11,59>::value;

但是,我得到“错误的模板参数数量(0,应该是1或更多)”。我想编译器试图在没有参数的情况下实例化min<>,但为什么呢?仅当min<a...>非零时才会调用sizeof...(a)

为什么我会收到此错误,我该如何解决?任何帮助表示赞赏。

4 个答案:

答案 0 :(得分:3)

评估两个分支,您可以使用专门化来解决这个问题:

template<int first, int...a>
struct min
{
    static const int value = (first > min<a...>::value) ? min<a...>::value : first;
};

template<int first>
struct min<first>
{
    static const int value = first;
};

答案 1 :(得分:3)

&&的短路行为并不会阻止编译器评估这两个表达式。 min<a...>::value仍然需要格式良好。因此,当a...变空时,您最终会得到min<>的实例化,而没有定义任何特化。

您可以通过专门针对单个参数来解决此问题:

template <int a>
struct min<a>
{
    static const int value = a;
};

答案 2 :(得分:1)

递归实例化一次删除一个参数。它是这样的:min<1, 2, 3>1与需要min<2, 3>的内容进行比较,然后min<3>实例化2以将其与min<3>进行比较。现在min<>尝试将3实例化以与template <int first,int...a> struct min { /* […] */ }; template <int first> struct min<first> { static const int value = first; }; 进行比较,这显然不起作用。

使用部分专业化。

{{1}}

如果您认为编译器没有实例化特殊化,如果它只包含在未评估的分支中:他必须验证表达式是否有效。

答案 3 :(得分:0)

旁注(不回答min&lt;&gt;的实例化)。 您可以使用constepr函数来评估模板和非模板参数:

#include <iostream>

// Single Value
template <typename T>
inline constexpr const T&
min_of(const T& a) {
    return a;
}

// Multiple Values
template <typename T, typename ...Args>
inline constexpr const T&
min_of(const T& a, const T& b, const Args& ...args) {
    // std::min as constexpr is C++14
    return min_of((a < b) ? a : b, args...);
}

// Template Arguments
template <int A, int ... Other>
constexpr int min_of() {
    return min_of(A, Other...);
}


// Test
template <int Value>
void print() {
    std::cout << "   template: " << Value << '\n';
}

int main() {
    print<min_of<42,97,11,59>()>();
    std::cout << "no template: " << min_of(42,97,11,59) << '\n';
    return 0;
}