问题 模板参数与函数参数[关闭]


以下2段代码有什么区别:

1:

template<size_t min, size_t max>
bool byLength(const std::string& v)
{
    return v.length() >= min && v.length() <= max;
}

2:

bool byLength(const std::string& v, size_t min, size_t max)
{
    return v.length() >= min && v.length() <= max;
}

使用模板参数而不是函数参数的主要用例是什么?为什么不只是使用第二个例子?


2239
2018-02-04 13:11


起源

模板已解决了 编译时间,参数评估在 运行。这意味着模板参数必须是常量才能由编译器解析,而函数参数可以是在编译​​时无法评估的use-input之类的东西。 - Some programmer dude
好吧,看起来我理解问题的愚蠢。我可以删除它吗? - Victor Polevoy
你不同地打电话给他们: byLength<min, max>(string) VS byLength(string, min, max)。如果这对你的眼睛有所影响。 - rubikonx9
可能重复 C ++函数作为Template Argument vs Parameter传递 - Jonathan Mee


答案:


以下2段代码有什么区别?

模板参数必须是常量,在编译时指定。函数参数是变量,不必在编译时知道。

为了说明,使用模板:

byLength<5,10>(v);     // OK

size_t min,max;
std::cin >> min >> max;
byLength<min,max>(v);  // ERROR: must be constants

而使用函数参数:

byLength(v, 5, 10);     // OK

size_t min,max;
std::cin >> min >> max;
byLength(v, min, max);  // OK

使用模板参数而不是函数参数的主要用例是什么?

作为常量,它们可以提供更好的优化,并且可以在仅允许常量的情况下(例如数组的大小)使用。

为什么不只是使用第二个例子?

在这种情况下,为什么不呢?这样会更灵活,因为您可以在运行时计算参数,或者从程序的输入中获取它们。如果它是内联的,那么当使用常量值调用时,它应该与模板一样高效。


10
2018-02-04 13:20





最大的区别在于你可以用这两个功能做什么:

  • 模板函数将其两个限制作为模板的参数,这意味着它们必须在编译时知道
  • 常规函数将其两个限制作为常规参数,这意味着您可以使用变量。

基本上,第二个功能可以让你这样做

int a, b;
cout << "Please enter two limits: ";
cin >> a >> b;
string s("quick brown fox");
bool res = byLength(s, a, b);

使用模板功能无法做到这一点:

int a, b;
cout << "Please enter two limits: ";
cin >> a >> b;
string s("quick brown fox");
bool res = byLength<a,b>(s); // <<== DOES NOT COMPILE.

如果所有调用都使用限制参数的常量表达式,则模板函数可以让您节省一些额外的CPU周期,因为编译器可以更好地进行优化。很难想象这些额外周期会产生有意义的差异的情况。

为什么不只是使用第二个例子?

在某些情况下,您需要在函数中使用编译时常量。例如,如果您想申报 std::array<len> 根据其中一个参数,它需要作为模板参数传递,而不是作为常规参数传递:

template<size_t sz>
void demo() {
    std::array<sz> data;
    ...
}

同样不适用于常规函数参数:

void demo(size_t sz) {
    std::array<sz> data; // <<== DOES NOT COMPILE.
    ...
}

3
2018-02-04 13:20





您不能使用不是的值调用模板 consexpr

最简单的例子是这样的:

1可以使用此代码调用:

const auto Min = numeric_limits<int>::min();
const auto Max = numeric_limits<int>::max();

byLength<Min, Max>(string());

您必须使用2表示仅在运行时已知的值:

cin >> Min >> Max;

// Cannot call by byLength<Min, Max>(string()); because the values are not constexpr
byLength(string(), Min, Max);

1
2018-02-04 13:25