C++ 模板,默认参数作为方法
C++ templates, default argument as a method
对于此选择排序的实现:
template <typename Iterator, typename Compare>
void sort(Iterator begin, Iterator end, Compare comp) {
for (auto i = begin; i != end; ++i) {
auto min = i;
for (auto j = i + 1; j != end; ++j) {
if (comp(*j, *min)) {
min = j;
}
}
std::swap(*min, *i);
}
}
如果 sort 方法跳过了最后一个参数,我应该如何修改它以便 Compare comp
应该是 std::less
方法?
我通过引入另一种方法尝试了函数重载:
template <typename Iterator>
void sort(Iterator begin, Iterator end) {
sort(begin, end, std::less<std::iterator_traits<Iterator>::value_type>());
}
但它给出了如下错误:
In file included from ../src/selection_sort_demo.cpp:1:
../include/selection_sort.hpp:24:29: error: template argument for template type parameter must be a type; did you forget 'typename'?
sort(begin, end, std::less<std::iterator_traits<Iterator>::value_type>());
^
typename
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../include/c++/6.3.1/bits/stl_function.h:380:21: note: template parameter is declared here
template<typename _Tp>
^
In file included from ../src/selection_sort_demo.cpp:1:
../include/selection_sort.hpp:24:2: error: call to 'sort' is ambiguous
sort(begin, end, std::less<std::iterator_traits<Iterator>::value_type>());
^~~~
../src/selection_sort_demo.cpp:22:13: note: in instantiation of function template specialization 'selection::sort<__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > >' requested here
selection::sort(v.begin(), v.end());
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../include/c++/6.3.1/bits/stl_algo.h:4727:5: note: candidate function [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >, _Compare = std::less<int>]
sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
^
../include/selection_sort.hpp:7:6: note: candidate function [with Iterator = __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >, Compare = std::less<int>]
void sort(Iterator begin, Iterator end, Compare comp)
^
2 errors generated.
[2/4] Compiling cpp object 'test/testexe@exe/selection_sort_test.cpp.o'
FAILED: test/testexe@exe/selection_sort_test.cpp.o
clang++ '-Itest/testexe@exe' '-Itest' '-I../test' '-I../include' '-Wall' '-Winvalid-pch' '-Wnon-virtual-dtor' '-std=c++14' '-O0' '-g' '-pthread' '-MMD' '-MQ' 'test/testexe@exe/selection_sort_test.cpp.o' '-MF' 'test/testexe@exe/selection_sort_test.cpp.o.d' -o 'test/testexe@exe/selection_sort_test.cpp.o' -c ../test/selection_sort_test.cpp
In file included from ../test/selection_sort_test.cpp:2:
../include/selection_sort.hpp:24:29: error: template argument for template type parameter must be a type; did you forget 'typename'?
sort(begin, end, std::less<std::iterator_traits<Iterator>::value_type>());
^
typename
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../include/c++/6.3.1/bits/stl_function.h:380:21: note: template parameter is declared here
template<typename _Tp>
^
In file included from ../test/selection_sort_test.cpp:2:
../include/selection_sort.hpp:24:2: error: call to 'sort' is ambiguous
sort(begin, end, std::less<std::iterator_traits<Iterator>::value_type>());
^~~~
../test/selection_sort_test.cpp:17:13: note: in instantiation of function template specialization 'selection::sort<__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > >' requested here
selection::sort(v1.begin(), v1.end());
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../include/c++/6.3.1/bits/stl_algo.h:4727:5: note: candidate function [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >, _Compare = std::less<int>]
sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
^
../include/selection_sort.hpp:7:6: note: candidate function [with Iterator = __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >, Compare = std::less<int>]
void sort(Iterator begin, Iterator end, Compare comp)
^
2 errors generated.
因为它是 c++14:
template <typename Iterator, typename Compare = std::less<> >
void sort(Iterator begin, Iterator end, Compare comp = Compare())
{
for (auto i = begin; i != end; ++i) {
auto min = i;
for (auto j = i + 1; j != end; ++j) {
if (comp(*j, *min)) {
min = j;
}
}
std::swap(*min, *i);
}
}
c++11:
template <typename Iterator, typename Compare = std::less< typename std::iterator_traits<Iterator>::value_type > >
void sort(Iterator begin, Iterator end, Compare comp = Compare())
{
for (auto i = begin; i != end; ++i) {
auto min = i;
for (auto j = i + 1; j != end; ++j) {
if (comp(*j, *min)) {
min = j;
}
}
std::swap(*min, *i);
}
}
解释:
我们必须为编译器提供模板参数列表中的默认类型和默认函数参数列表。
有关 std::less<> 自 c++14 以来的解释,请参阅:
你是对的,但是忘记了 typename
关键字。检查这个:
template <typename Iterator>
void sort(Iterator begin, Iterator end) {
sort(begin, end, std::less<typename std::iterator_traits<Iterator>::value_type>());
}
可能您需要默认模板参数,但这也适用。
对于此选择排序的实现:
template <typename Iterator, typename Compare>
void sort(Iterator begin, Iterator end, Compare comp) {
for (auto i = begin; i != end; ++i) {
auto min = i;
for (auto j = i + 1; j != end; ++j) {
if (comp(*j, *min)) {
min = j;
}
}
std::swap(*min, *i);
}
}
如果 sort 方法跳过了最后一个参数,我应该如何修改它以便 Compare comp
应该是 std::less
方法?
我通过引入另一种方法尝试了函数重载:
template <typename Iterator>
void sort(Iterator begin, Iterator end) {
sort(begin, end, std::less<std::iterator_traits<Iterator>::value_type>());
}
但它给出了如下错误:
In file included from ../src/selection_sort_demo.cpp:1:
../include/selection_sort.hpp:24:29: error: template argument for template type parameter must be a type; did you forget 'typename'?
sort(begin, end, std::less<std::iterator_traits<Iterator>::value_type>());
^
typename
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../include/c++/6.3.1/bits/stl_function.h:380:21: note: template parameter is declared here
template<typename _Tp>
^
In file included from ../src/selection_sort_demo.cpp:1:
../include/selection_sort.hpp:24:2: error: call to 'sort' is ambiguous
sort(begin, end, std::less<std::iterator_traits<Iterator>::value_type>());
^~~~
../src/selection_sort_demo.cpp:22:13: note: in instantiation of function template specialization 'selection::sort<__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > >' requested here
selection::sort(v.begin(), v.end());
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../include/c++/6.3.1/bits/stl_algo.h:4727:5: note: candidate function [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >, _Compare = std::less<int>]
sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
^
../include/selection_sort.hpp:7:6: note: candidate function [with Iterator = __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >, Compare = std::less<int>]
void sort(Iterator begin, Iterator end, Compare comp)
^
2 errors generated.
[2/4] Compiling cpp object 'test/testexe@exe/selection_sort_test.cpp.o'
FAILED: test/testexe@exe/selection_sort_test.cpp.o
clang++ '-Itest/testexe@exe' '-Itest' '-I../test' '-I../include' '-Wall' '-Winvalid-pch' '-Wnon-virtual-dtor' '-std=c++14' '-O0' '-g' '-pthread' '-MMD' '-MQ' 'test/testexe@exe/selection_sort_test.cpp.o' '-MF' 'test/testexe@exe/selection_sort_test.cpp.o.d' -o 'test/testexe@exe/selection_sort_test.cpp.o' -c ../test/selection_sort_test.cpp
In file included from ../test/selection_sort_test.cpp:2:
../include/selection_sort.hpp:24:29: error: template argument for template type parameter must be a type; did you forget 'typename'?
sort(begin, end, std::less<std::iterator_traits<Iterator>::value_type>());
^
typename
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../include/c++/6.3.1/bits/stl_function.h:380:21: note: template parameter is declared here
template<typename _Tp>
^
In file included from ../test/selection_sort_test.cpp:2:
../include/selection_sort.hpp:24:2: error: call to 'sort' is ambiguous
sort(begin, end, std::less<std::iterator_traits<Iterator>::value_type>());
^~~~
../test/selection_sort_test.cpp:17:13: note: in instantiation of function template specialization 'selection::sort<__gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > > >' requested here
selection::sort(v1.begin(), v1.end());
^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/6.3.1/../../../../include/c++/6.3.1/bits/stl_algo.h:4727:5: note: candidate function [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >, _Compare = std::less<int>]
sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
^
../include/selection_sort.hpp:7:6: note: candidate function [with Iterator = __gnu_cxx::__normal_iterator<int *, std::vector<int, std::allocator<int> > >, Compare = std::less<int>]
void sort(Iterator begin, Iterator end, Compare comp)
^
2 errors generated.
因为它是 c++14:
template <typename Iterator, typename Compare = std::less<> >
void sort(Iterator begin, Iterator end, Compare comp = Compare())
{
for (auto i = begin; i != end; ++i) {
auto min = i;
for (auto j = i + 1; j != end; ++j) {
if (comp(*j, *min)) {
min = j;
}
}
std::swap(*min, *i);
}
}
c++11:
template <typename Iterator, typename Compare = std::less< typename std::iterator_traits<Iterator>::value_type > >
void sort(Iterator begin, Iterator end, Compare comp = Compare())
{
for (auto i = begin; i != end; ++i) {
auto min = i;
for (auto j = i + 1; j != end; ++j) {
if (comp(*j, *min)) {
min = j;
}
}
std::swap(*min, *i);
}
}
解释:
我们必须为编译器提供模板参数列表中的默认类型和默认函数参数列表。
有关 std::less<> 自 c++14 以来的解释,请参阅:
你是对的,但是忘记了 typename
关键字。检查这个:
template <typename Iterator>
void sort(Iterator begin, Iterator end) {
sort(begin, end, std::less<typename std::iterator_traits<Iterator>::value_type>());
}
可能您需要默认模板参数,但这也适用。