函数调用中 std::array 中元素的确切数量

Exact number of elements in std::array in function call

提问人:Urwald 提问时间:10/17/2023 更新时间:10/17/2023 访问量:164

问:

我有一个函数,它采用给定的大小std::arrayN

void func(std::array<int,3> x) {
  // do something
}

int main() {
  func({4,4,4}) // works
  func({4}) // works as well
}

我明白为什么第二个调用也有效,我的问题是:有没有办法在编译时检查我实际传递了多少个参数?

背景:我不想允许第二次调用,我希望用户准确地传递参数。N

C++ 元编程 stdarray

评论

0赞 Some programmer dude 10/17/2023
一个数组具有固定数量的元素,数组中的元素永远不会少于(或更多)三个。也许你应该使用或代替?std::array<int, 3>std::vectorstd::initializer_list
0赞 Quimby 10/17/2023
可以接受吗?std::tuple<int,int,int>
1赞 Sam Varshavchik 10/17/2023
不,由于C++的一些基本规则,这无法完成。
2赞 Some programmer dude 10/17/2023
您试图解决的实际和根本问题是什么?请直接询问。
1赞 Aconcagua 10/17/2023
数组中值的语义/含义是什么?使用自定义结构可能是一个更好的选择,为其中任何一个提供清晰的名称(例如,如果一个适当的构造函数接受三个参数,也可以强制执行您的意图。struct Point3D { int x; int y; int z; };

答:

15赞 Pepijn Kramer 10/17/2023 #1

您可以像这样使函数更具限制性:

#include <type_traits>
    
// let sfinae disable mismatches
template<std::size_t N>
auto func(const int (&v)[N]) -> std::enable_if_t<N==3,void>
{
  // do something
}
        
int main() 
{
    func({4,4,4}); // works
    func({4}); // no longer compiles
}

演示 : https://onlinegdb.com/FHlRINqCZ

评论

10赞 cigien 10/17/2023
除此之外,它可能还值得一提,因为它的意图更具可读性。-> std::enable_if_t<N==3,void>requires (N == 3)
2赞 Pepijn Kramer 10/17/2023
@cigien 我通常在 C++17 上进行测试(我认为这是一个广泛使用的版本),但您的版本是 C++20 的一个受欢迎的补充
0赞 Pepijn Kramer 10/17/2023
我忘了提到,当您使用模板(像这样)时,不会考虑所有隐式类型转换。当我希望函数仅显式匹配类型时,这是我更经常使用的属性
4赞 Jarod42 10/17/2023 #2

或者,可以添加已删除的重载:

void func(std::array<int, 3>) {
  // do something
}

template <std::size_t N>
requires (N != 3)
void func(const int(&)[N]) = delete;

演示