c ++函数模板,没有任意参数

时间:2014-08-08 18:08:06

标签: c++ templates

考虑这个可行的c ++代码:

template <size_t N>
int check(std::array<unsigned char, N> buf){
    std::cout << N << "-" << buf.size() << std::endl;
    return 0;
}


int main (int argc, char *argv[])
{
    std::array<unsigned char, 20> a;
    std::array<unsigned char, 30> b;
    std::array<unsigned char, 40> c;

    check(a);
    check(b);
    check(c);

    return 0;
}

是否可以明确地实例化&#34;检查&#34;对于N = 20和N = 30,但禁用任何其他隐式实例化?

这意味着如果我使用&#34; check(c)&#34;,

,我想得到编译时错误

编辑:

实际上我想拥有相同的实现,所以模板是正确的选择,如果由于某种原因我用一个不应该存在的参数实例化它,我想要编译时错误。 因此,static_assert(c ++ 11)解决方案看起来最好,问题完整且非常易读。

5 个答案:

答案 0 :(得分:4)

如果static_assert不是20或30,则可以使用N抛出编译时错误。

template <size_t N>
int check(std::array<unsigned char, N> buf) 
{
    static_assert(N == 20 || N == 30, "N must be 20 or 30.");

    std::cout << N << "-" << buf.size() << std::endl;

    return 0;
}

答案 1 :(得分:3)

您可以使用static_assert

template <size_t N>
    int check(std::array<unsigned char, N> buf){
    static_assert(N==20 || N==30, "invalid value of N");
    std::cout << N << "-" << buf.size() << std::endl;
    return 0;
}

对于N的无效值,它将导致编译时错误。见live.

答案 2 :(得分:2)

有几种方法可以做到这一点。

一种方法是:

template <size_t N>
typename std::enable_if<N == 20 || N == 30, int>::type
check(std::array<unsigned char, N> buf) {
  //..
}

关于选择此问题与其他答案中显示的static_assert之间的一些想法:

    某些人可能会将
  • static_assert视为比enable_if
  • 更清晰明确地表达您的约束
  • (在我看来最重要的区别):这种约束是函数接口的一部分,即函数的定义表达约束。 static_assert是实施的一部分。在更复杂的代码中,这甚至可以影响函数的重载方式。
  • 使用static_assert,您可以清楚地知道在不满足约束条件时出现的问题。

答案 3 :(得分:0)

另一种方法是删除函数:

template <size_t N>
void check(std::array<unsigned char, N> buf) = delete;

void check(std::array<unsigned char, 20> buf)
{
    std::cout << 20 << "-" << buf.size() << std::endl;
}

void check(std::array<unsigned char, 30> buf)
{
    std::cout << 30 << "-" << buf.size() << std::endl;
}

Live example

答案 4 :(得分:0)

如果您对数组的处理方式不同,那么模板在您的情况下是无用的。 只是提供一些重载:

#include <array>
#include <iostream>

int check(std::array<unsigned char, 20> buf){
    std::cout << "Handling an array of size 20\n";
    return 0;
}

int check(std::array<unsigned char, 30> buf){
    std::cout << "Handling an array of size 30\n";
    return 0;
}
int check(std::array<unsigned char, 40> buf){
    std::cout << "Handling an array of size 40\n";
    return 0;
}


int main (int argc, char *argv[])
{
    std::array<unsigned char, 20> a;
    std::array<unsigned char, 30> b;
    std::array<unsigned char, 40> c;

    check(a);
    check(b);
    check(c);

    // std::array<unsigned char, 0> d;
    //error: no matching function for call to ‘check(std::array<unsigned char, 0ul>&)'
    //check(d);

    return 0;
}

否则,如果代码相同,则static_assert是不错的选择(参见@Joachim Pileborg评论)