Why doesn't universal reference apply for arrays?
up vote
4
down vote
favorite
#include <type_traits>
template<typename T>
void f(const T&)
static_assert(std::is_array_v<T>); // ok
template<typename T>
void g(T&&)
static_assert(std::is_array_v<T>); // error
int main()
char arr[8];
f(arr); // ok
g(arr); // error
My compiler is clang 7.0 with -std=c++17
.
Why doesn't universal reference apply for arrays?
c++ c++11 standards perfect-forwarding forwarding-reference
add a comment |
up vote
4
down vote
favorite
#include <type_traits>
template<typename T>
void f(const T&)
static_assert(std::is_array_v<T>); // ok
template<typename T>
void g(T&&)
static_assert(std::is_array_v<T>); // error
int main()
char arr[8];
f(arr); // ok
g(arr); // error
My compiler is clang 7.0 with -std=c++17
.
Why doesn't universal reference apply for arrays?
c++ c++11 standards perfect-forwarding forwarding-reference
add a comment |
up vote
4
down vote
favorite
up vote
4
down vote
favorite
#include <type_traits>
template<typename T>
void f(const T&)
static_assert(std::is_array_v<T>); // ok
template<typename T>
void g(T&&)
static_assert(std::is_array_v<T>); // error
int main()
char arr[8];
f(arr); // ok
g(arr); // error
My compiler is clang 7.0 with -std=c++17
.
Why doesn't universal reference apply for arrays?
c++ c++11 standards perfect-forwarding forwarding-reference
#include <type_traits>
template<typename T>
void f(const T&)
static_assert(std::is_array_v<T>); // ok
template<typename T>
void g(T&&)
static_assert(std::is_array_v<T>); // error
int main()
char arr[8];
f(arr); // ok
g(arr); // error
My compiler is clang 7.0 with -std=c++17
.
Why doesn't universal reference apply for arrays?
c++ c++11 standards perfect-forwarding forwarding-reference
c++ c++11 standards perfect-forwarding forwarding-reference
asked Nov 8 at 10:44
xmllmx
13.1k880201
13.1k880201
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
up vote
11
down vote
accepted
First of all, these are officially called "forwarding references", not "universal references".
Your static_assert
fails due to the fact that T
is deduced as T&
when passing an lvalue to a function taking a "forwarding reference" - this is one of the special rules of "forwarding references" that apply during template argument deduction.
You can fix your assert by stripping any reference out first:
static_assert(std::is_array_v<std::remove_cvref_t<T>>);
live example on godbolt.org
std::remove_cvref_t
is a bleeding edge C++20 feature - you might want to use std::remove_reference_t
instead if your compiler doesn't support it.
add a comment |
up vote
0
down vote
The relevant rule here when the template argument deduction takes place is:
Deduction from a function call
...
4. If P is an rvalue reference to a cv-unqualified template parameter (so-called forwarding reference), and the corresponding function call argument is an lvalue, the type lvalue reference to A is used in place of A for deduction.
So in your case, arr
is being deduced as reference to arr
and thus the static_assert
fails.
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
11
down vote
accepted
First of all, these are officially called "forwarding references", not "universal references".
Your static_assert
fails due to the fact that T
is deduced as T&
when passing an lvalue to a function taking a "forwarding reference" - this is one of the special rules of "forwarding references" that apply during template argument deduction.
You can fix your assert by stripping any reference out first:
static_assert(std::is_array_v<std::remove_cvref_t<T>>);
live example on godbolt.org
std::remove_cvref_t
is a bleeding edge C++20 feature - you might want to use std::remove_reference_t
instead if your compiler doesn't support it.
add a comment |
up vote
11
down vote
accepted
First of all, these are officially called "forwarding references", not "universal references".
Your static_assert
fails due to the fact that T
is deduced as T&
when passing an lvalue to a function taking a "forwarding reference" - this is one of the special rules of "forwarding references" that apply during template argument deduction.
You can fix your assert by stripping any reference out first:
static_assert(std::is_array_v<std::remove_cvref_t<T>>);
live example on godbolt.org
std::remove_cvref_t
is a bleeding edge C++20 feature - you might want to use std::remove_reference_t
instead if your compiler doesn't support it.
add a comment |
up vote
11
down vote
accepted
up vote
11
down vote
accepted
First of all, these are officially called "forwarding references", not "universal references".
Your static_assert
fails due to the fact that T
is deduced as T&
when passing an lvalue to a function taking a "forwarding reference" - this is one of the special rules of "forwarding references" that apply during template argument deduction.
You can fix your assert by stripping any reference out first:
static_assert(std::is_array_v<std::remove_cvref_t<T>>);
live example on godbolt.org
std::remove_cvref_t
is a bleeding edge C++20 feature - you might want to use std::remove_reference_t
instead if your compiler doesn't support it.
First of all, these are officially called "forwarding references", not "universal references".
Your static_assert
fails due to the fact that T
is deduced as T&
when passing an lvalue to a function taking a "forwarding reference" - this is one of the special rules of "forwarding references" that apply during template argument deduction.
You can fix your assert by stripping any reference out first:
static_assert(std::is_array_v<std::remove_cvref_t<T>>);
live example on godbolt.org
std::remove_cvref_t
is a bleeding edge C++20 feature - you might want to use std::remove_reference_t
instead if your compiler doesn't support it.
answered Nov 8 at 10:46
Vittorio Romeo
54.8k16144283
54.8k16144283
add a comment |
add a comment |
up vote
0
down vote
The relevant rule here when the template argument deduction takes place is:
Deduction from a function call
...
4. If P is an rvalue reference to a cv-unqualified template parameter (so-called forwarding reference), and the corresponding function call argument is an lvalue, the type lvalue reference to A is used in place of A for deduction.
So in your case, arr
is being deduced as reference to arr
and thus the static_assert
fails.
add a comment |
up vote
0
down vote
The relevant rule here when the template argument deduction takes place is:
Deduction from a function call
...
4. If P is an rvalue reference to a cv-unqualified template parameter (so-called forwarding reference), and the corresponding function call argument is an lvalue, the type lvalue reference to A is used in place of A for deduction.
So in your case, arr
is being deduced as reference to arr
and thus the static_assert
fails.
add a comment |
up vote
0
down vote
up vote
0
down vote
The relevant rule here when the template argument deduction takes place is:
Deduction from a function call
...
4. If P is an rvalue reference to a cv-unqualified template parameter (so-called forwarding reference), and the corresponding function call argument is an lvalue, the type lvalue reference to A is used in place of A for deduction.
So in your case, arr
is being deduced as reference to arr
and thus the static_assert
fails.
The relevant rule here when the template argument deduction takes place is:
Deduction from a function call
...
4. If P is an rvalue reference to a cv-unqualified template parameter (so-called forwarding reference), and the corresponding function call argument is an lvalue, the type lvalue reference to A is used in place of A for deduction.
So in your case, arr
is being deduced as reference to arr
and thus the static_assert
fails.
answered Nov 8 at 11:05
P.W
6,8941437
6,8941437
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53206090%2fwhy-doesnt-universal-reference-apply-for-arrays%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password