I have the following testcase:
#include <type_traits>
template <typename Ty_>
using conditional_ref =
typename std::conditional<std::is_fundamental<Ty_>::value, Ty_, Ty_ const&>::type;
template <typename Ty_, typename Ty2_ = conditional_ref<Ty_>>
inline void f(Ty2_ arg1) {
static_assert(std::is_same<Ty2_, conditional_ref<Ty_>>::value, "uh-oh!");
}
int main() {
struct A {};
A a{};
double b{};
//f(a); // Cannot deduce parameter (expected)
//f(b); // Cannot deduce parameter (expected)
f<decltype(a)>(a); // uh-oh!
f<decltype(b)>(b); // OK
f<decltype(a), conditional_ref<decltype(a)>>(a); // OK
f<decltype(b), conditional_ref<decltype(b)>>(b); // OK
return 0;
}
In this, f<decltype(a)>
deduces to f<A, A>
instead of the expected f<A, A const&>
.
I have tried in clang-10, gcc-9, and Visual Studio 2019; all of these give the same result, so I think I'm doing something wrong.
Example output from clang-10:
$ clang-10 test.cpp
test.cpp:9:3: error: static_assert failed due to requirement 'std::is_same<A, const A &>::value' "uh-oh!"
static_assert(std::is_same<Ty2_, conditional_ref<Ty_>>::value, "uh-oh!");
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:19:3: note: in instantiation of function template specialization 'f<A, A>' requested here
f<decltype(a)>(a); // uh-oh!
^
1 error generated.
Why is the template deduction not what I expect here?
How do I rewrite f()
so that it accepts a Ty_
when passed a fundamental type, and a Ty_ const&
otherwise? Preferably while only having to pass the type of the argument once, like f<decltype(a)>(a)
.
Aucun commentaire:
Enregistrer un commentaire