argument-deduction

C++20 designated initializers with templated types

岁酱吖の 提交于 2019-12-08 17:00:48
问题 How are designated initializers (C++20) supposed to work with CTAD? This code works fine in gcc9.2, but fails with clang8 template <typename int_t=int, typename float_t=float> struct my_pair { int_t first; float_t second; }; template<typename ... ts> my_pair(ts...) -> my_pair<ts...>; int main() { my_pair x{.first = 20, .second = 20.f}; static_assert( std::is_same_v<decltype(x.first), int> ); static_assert( std::is_same_v<decltype(x.second), float> ); } Is this supposed to be valid? See an

Type deduction for non-viable function templates

与世无争的帅哥 提交于 2019-12-07 14:18:12
问题 In his answer to this question and the comment section, Johannes Schaub says there's a "match error" when trying to do template type deduction for a function template that requires more arguments than have been passed: template<class T> void foo(T, int); foo(42); // the template specialization foo<int>(int, int) is not viable In the context of the other question, what's relevant is whether or not type deduction for the function template succeeds (and substitution takes place): template<class

Type deduction for non-viable function templates

喜欢而已 提交于 2019-12-05 18:32:56
In his answer to this question and the comment section, Johannes Schaub says there's a "match error" when trying to do template type deduction for a function template that requires more arguments than have been passed: template<class T> void foo(T, int); foo(42); // the template specialization foo<int>(int, int) is not viable In the context of the other question, what's relevant is whether or not type deduction for the function template succeeds (and substitution takes place): template<class T> struct has_no_nested_type {}; // I think you need some specialization for which the following class

Do we still need to write the empty angle brackets when using transparent std function objects?

。_饼干妹妹 提交于 2019-12-03 23:27:45
With class template argument deduction we can write: std::less Fn; However, G++ 8.2 rejects this code: #include <algorithm> #include <vector> #include <functional> int main() { std::vector v= { 1, 3, 2, 7, 5, 4 }; std::sort(v.begin(),v.end(),std::greater()); } emitting the following error: error: cannot deduce template arguments for 'greater' from () Clang++ 7.0 and MSVC 15.8.0 compile it without warnings. Which compiler is right? GCC is wrong. There is already a bug report . [dcl.type.simple]/2 says: A type-specifier of the form typename opt nested-name-specifier opt template-name is a

Nested template argument deduction for class templates not working

家住魔仙堡 提交于 2019-12-03 16:20:51
问题 In this Q&A I wrote a little wrapper class that provides reverse iterator access to a range, relying on the c++1z language feature template argument deduction for class templates (p0091r3, p0512r0) #include <iostream> #include <iterator> #include <vector> template<class Rng> class Reverse { Rng const& rng; public: Reverse(Rng const& r) noexcept : rng(r) {} auto begin() const noexcept { using std::end; return std::make_reverse_iterator(end(rng)); } auto end() const noexcept { using std::begin;

Template default argument loses its reference type

本小妞迷上赌 提交于 2019-12-03 14:22:44
问题 Consider #include <iostream> #include <type_traits> template <class T, class ARG_T = T&> T foo(ARG_T v){ return std::is_reference<decltype(v)>::value; } int main() { int a = 1; std::cout << foo<int>(a) << '\n'; std::cout << foo<int, int&>(a) << '\n'; } I'd expect the output to be 1 in both cases. But in the first case it's 0: consistent with the default being class ARG_T = T rather than class ARG_T = T& . What am I missing? 回答1: For foo<int>(a) , ARG_T is being deduced from a , and is not

Template Argument Deduction Failure and Function Parameters/Arguments Mismatch

心不动则不痛 提交于 2019-12-03 12:25:35
Consider the following program: template <class T> struct A { using X = typename T::X; }; template <class T, typename A<T>::X* = nullptr> void f(T, int); void f(...); template <class T> void g(T, int, typename A<T>::X* = nullptr); // # void g(...); int main() { // f(0, nullptr); // error g(0, nullptr); // ok } g(0, nullptr) compiles while f(0, nullptr) does not (tested under GCC trunk and Clang trunk on Godbolt ). It seems that during the template argument deduction process of # , the compiler does not instantiate A<int> when it finds the argument nullptr does not match the parameter int .

Nested template argument deduction for class templates not working

混江龙づ霸主 提交于 2019-12-03 06:29:41
In this Q&A I wrote a little wrapper class that provides reverse iterator access to a range, relying on the c++1z language feature template argument deduction for class templates ( p0091r3 , p0512r0 ) #include <iostream> #include <iterator> #include <vector> template<class Rng> class Reverse { Rng const& rng; public: Reverse(Rng const& r) noexcept : rng(r) {} auto begin() const noexcept { using std::end; return std::make_reverse_iterator(end(rng)); } auto end() const noexcept { using std::begin; return std::make_reverse_iterator(begin(rng)); } }; int main() { std::vector<int> my_stack; my

Template default argument loses its reference type

依然范特西╮ 提交于 2019-12-03 04:12:06
Consider #include <iostream> #include <type_traits> template <class T, class ARG_T = T&> T foo(ARG_T v){ return std::is_reference<decltype(v)>::value; } int main() { int a = 1; std::cout << foo<int>(a) << '\n'; std::cout << foo<int, int&>(a) << '\n'; } I'd expect the output to be 1 in both cases. But in the first case it's 0: consistent with the default being class ARG_T = T rather than class ARG_T = T& . What am I missing? For foo<int>(a) , ARG_T is being deduced from a , and is not taken from the default template argument. Since it's a by value function parameter, and a is an expression of

How does template argument deduction work when an overloaded function is involved as an argument?

ぃ、小莉子 提交于 2019-12-01 02:15:01
This is the more sophisticated question mentioned in How does overload resolution work when an argument is an overloaded function? Below code compiles without any problem : void foo() {} void foo(int) {} void foo(double) {} void foo(int, double) {} // Uncommenting below line break compilation //template<class T> void foo(T) {} template<class X, class Y> void bar(void (*f)(X, Y)) { f(X(), Y()); } int main() { bar(foo); } It doesn't appear a challenging task for template argument deduction - there is only one function foo() that accepts two arguments. However, uncommenting the template overload