简体   繁体   English

std::enable_if_t 和 std::array 实现

[英]std::enable_if_t and std::array implementation

How can I use this function?我该如何使用这个 function? (syntax) (句法)

template<typename T, typename = std::enable_if_t<std::is_array_v<T>>>
void foo(T&& a)
{
  std::cout << a.size() << std::endl;
}

because this is error因为这是错误

std::array<std::string, 3> arr { "1", "2", "3" };
foo<std::array<std::string, 3>>(arr);

this error too这个错误也是

std::array<std::string, 3> arr { "1", "2", "3" };
foo<>(arr);

this error too这个错误也是

std::array<std::string, 3> arr { "1", "2", "3" };
foo<std::array<std::string, 3>, 3>(arr);

link: https://godbolt.org/z/ToMeGe5d5链接: https://godbolt.org/z/ToMeGe5d5

The function is constrained so that it accepts only built-in arrays as argument, not std::array . function 受到约束,因此它只接受内置的arrays 作为参数,而不是std::array std::is_array_v tests only for built-in arrays. std::is_array_v仅测试内置 arrays。

Also, functions with forwarding references as function parameter ( T&& where T is a template parameter) are not expected to have the corresponding type template argument (for T ) specified explicitly.此外,转发引用为 function 参数( T&&其中T是模板参数)的函数不应具有显式指定的相应类型模板参数(对于T )。 So just drop the template argument list in the call completely.因此,只需完全删除调用中的模板参数列表。 It is supposed to be deduced, otherwise the forwarding reference will not work as intended.它应该是推导出来的,否则转发引用将无法按预期工作。

For example:例如:

std::string arr[] = { "1", "2", "3" };
foo(arr);

But then the function specialization will fail to instantiate, because built-in arrays don't have members that can be referred to with the member access operator as in a.size() .但是随后 function 特化将无法实例化,因为内置 arrays 没有可以使用成员访问运算符引用的成员,如a.size() So the function is not usable at all.所以 function 根本不可用。 (I am not sure whether you made a mistake here reducing the actual function to an example or whether you are trying to write a function accepting std::array yourself, in which case the other answers are giving good suggestions.) (我不确定您在这里是否犯了错误,将实际的 function 简化为示例,或者您是否尝试编写 function 自己接受std::array ,在这种情况下,其他答案给出了很好的建议。)

std::is_array_v<std::array<T, N>> yields false for any T and N . std::is_array_v<std::array<T, N>>对任何TN产生false You need to create a custom type trait or simply write the function differently:您需要创建一个自定义类型特征或简单地以不同的方式编写 function:

template<typename T, size_t N>
void foo(std::array<T, N> const& a)
{
    std::cout << a.size() << std::endl;
}

or或者

template<class T>
struct is_std_array : std::false_type {};
 
template<class T, size_t N>
struct is_std_array<std::array<T, N>> : std::true_type {};

template<class T>
constexpr bool is_std_array_v = is_std_array<std::remove_cvref_t<T>>::value;

template<typename T, std::enable_if_t<is_std_array_v<T>, bool> = false>
void foo(T&& a)
{
    std::cout << a.size() << std::endl;
}

See godbolt神螺栓

That function is (almost [1] ) uncallable as written: function 是(几乎[1] )不可调用的书面:

  • std::is_array_v is only true for built-in C-style arrays. std::is_array_vtrue于内置 C 样式 arrays。 That is std::is_array_v<int[10]> is true , but std::is_array_v<std::array<int, 10>> is false .那就是std::is_array_v<int[10]>true ,但是std::is_array_v<std::array<int, 10>>false
  • Built-in C-style arrays do not have a size member function.内置 C 样式 arrays 没有size成员 function。

That means that for any parameter type that will satisfy your type constraint, the body of the function will fail to compile.这意味着对于任何满足类型约束的参数类型,function 的主体都将无法编译。


You don't really need a type constraint though.不过,您实际上并不需要类型约束。 You can just make your parameter a std::array :您可以将参数std::array

template<typename T, size_t N>
void foo(const std::array<T, N>& a)
{
  std::cout << a.size() << std::endl;
}

int main()
{
    std::array<int, 4> arr = {1, 2, 3, 4};
    foo(arr); // prints 4
}

Or if you're trying to get the size of a built-in C-style array:或者,如果您尝试获取内置 C 样式数组的大小:

template<typename T, size_t N>
void foo(const T(&a)[N])
{
  std::cout << N << std::endl;
}

int main()
{
  int arr[] = {1, 2, 3, 4};
  foo(arr); // prints 4
}

[1]: Technically foo<std::array<std::string, 3>&, void>(arr) works, but that's just because you've implemented the type check in such a way that it can be worked around by supplying something in place of the default template argument. [1]:从技术上讲foo<std::array<std::string, 3>&, void>(arr)有效,但这只是因为您已经以可以通过以下方式解决的类型检查实现了提供一些东西来代替默认的模板参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM