Why this code can't be compiled??

Discussion in 'C++' started by Wayne Shu, Nov 9, 2006.

  1. Wayne Shu

    Wayne Shu Guest

    The code is below:
    #include <iostream>
    #include <functional>

    template <typename T, typename FUN>
    void insert_sort(T *arr, size_t size, FUN f = std::less<T>())
    {
    for( int j = 1; j < size; j++ ){
    type key = arr[j];
    int i = j - 1;
    while( i >= 0 && f(arr, key) ){
    arr[i+1] = arr;
    i = i - 1;
    }
    arr[i+1] = key;
    }
    }

    template <typename T>
    void display(std::eek:stream &out, const T *arr, size_t size)
    {
    out << "<";
    for(size_t i = 0; i < size; ++i){
    out << arr << ((i == size - 1) ? ">" : " ");
    }
    }

    int main()
    {
    const int iarr[] = { 9, 8, 56, 784, 2, 7, 89, 4 };
    const double darr[] = { 7.8, 89.2, 45.0, 44.0, 9.6, 78.4, 999.0 };
    int *piarr = new int[sizeof(iarr) / sizeof(int)];
    double *pdarr = new double[sizeof(darr) / sizeof(double)];

    std::cout << "before sort:\n";
    display(std::cout, iarr, sizeof(iarr) / sizeof(int));

    // test for insert sort
    memcpy(piarr, iarr, sizeof(iarr));
    insert_sort(piarr, sizeof(iarr) / sizeof(int));
    std::cout << "after insort sort:\n";
    display(std::cout, piarr, sizeof(iarr) / sizeof(int));

    // test for insert sort
    memcpy(pdarr, darr, sizeof(darr));
    insert_sort(pdarr, sizeof(darr) / sizeof(double));
    std::cout << "after insort sort:\n";
    display(std::cout, pdarr, sizeof(darr) / sizeof(int));

    delete[] piarr;
    delete[] pdarr;

    return 0;
    }

    What's wrong??
    Why the default arguement doesn't work??

    Thanks.

    Regards
    Wayne Shu
     
    Wayne Shu, Nov 9, 2006
    #1
    1. Advertising

  2. Wayne Shu

    Eric Guest

    Wayne Shu wrote:
    > The code is below:
    > #include <iostream>
    > #include <functional>
    >
    > template <typename T, typename FUN>
    > void insert_sort(T *arr, size_t size, FUN f = std::less<T>())
    > {
    > for( int j = 1; j < size; j++ ){
    > type key = arr[j];
    > int i = j - 1;
    > while( i >= 0 && f(arr, key) ){
    > arr[i+1] = arr;
    > i = i - 1;
    > }
    > arr[i+1] = key;
    > }
    > }
    >
    > template <typename T>
    > void display(std::eek:stream &out, const T *arr, size_t size)
    > {
    > out << "<";
    > for(size_t i = 0; i < size; ++i){
    > out << arr << ((i == size - 1) ? ">" : " ");
    > }
    > }
    >
    > int main()
    > {
    > const int iarr[] = { 9, 8, 56, 784, 2, 7, 89, 4 };
    > const double darr[] = { 7.8, 89.2, 45.0, 44.0, 9.6, 78.4, 999.0 };
    > int *piarr = new int[sizeof(iarr) / sizeof(int)];
    > double *pdarr = new double[sizeof(darr) / sizeof(double)];
    >
    > std::cout << "before sort:\n";
    > display(std::cout, iarr, sizeof(iarr) / sizeof(int));
    >
    > // test for insert sort
    > memcpy(piarr, iarr, sizeof(iarr));
    > insert_sort(piarr, sizeof(iarr) / sizeof(int));
    > std::cout << "after insort sort:\n";
    > display(std::cout, piarr, sizeof(iarr) / sizeof(int));
    >
    > // test for insert sort
    > memcpy(pdarr, darr, sizeof(darr));
    > insert_sort(pdarr, sizeof(darr) / sizeof(double));
    > std::cout << "after insort sort:\n";
    > display(std::cout, pdarr, sizeof(darr) / sizeof(int));
    >
    > delete[] piarr;
    > delete[] pdarr;
    >
    > return 0;
    > }
    >
    > What's wrong??
    > Why the default arguement doesn't work??
    >
    > Thanks.
    >
    > Regards
    > Wayne Shu
    >


    What error do you get when you try to compile?
     
    Eric, Nov 9, 2006
    #2
    1. Advertising

  3. Wayne Shu wrote:

    > Why this code can't be compiled??


    Because it's not legal C++.

    > The code is below:
    > #include <iostream>
    > #include <functional>
    >
    > template <typename T, typename FUN>
    > void insert_sort(T *arr, size_t size, FUN f = std::less<T>())
    > {
    > for( int j = 1; j < size; j++ ){
    > type key = arr[j];


    What is "type"? It's not defined.

    > int i = j - 1;
    > while( i >= 0 && f(arr, key) ){
    > arr[i+1] = arr;
    > i = i - 1;
    > }
    > arr[i+1] = key;
    > }
    > }
    >
    > template <typename T>
    > void display(std::eek:stream &out, const T *arr, size_t size)
    > {
    > out << "<";
    > for(size_t i = 0; i < size; ++i){
    > out << arr << ((i == size - 1) ? ">" : " ");
    > }
    > }
    >
    > int main()
    > {
    > const int iarr[] = { 9, 8, 56, 784, 2, 7, 89, 4 };
    > const double darr[] = { 7.8, 89.2, 45.0, 44.0, 9.6, 78.4, 999.0 };
    > int *piarr = new int[sizeof(iarr) / sizeof(int)];
    > double *pdarr = new double[sizeof(darr) / sizeof(double)];
    >
    > std::cout << "before sort:\n";
    > display(std::cout, iarr, sizeof(iarr) / sizeof(int));
    >
    > // test for insert sort
    > memcpy(piarr, iarr, sizeof(iarr));
    > insert_sort(piarr, sizeof(iarr) / sizeof(int));


    There's no way for the compiler to deduce the type of FUN here. Change
    the above line to:

    insert_sort<int, std::less<int> >(piarr, sizeof(iarr) /
    sizeof(int));

    > std::cout << "after insort sort:\n";
    > display(std::cout, piarr, sizeof(iarr) / sizeof(int));
    >
    > // test for insert sort
    > memcpy(pdarr, darr, sizeof(darr));
    > insert_sort(pdarr, sizeof(darr) / sizeof(double));


    Again, there's no way for the compiler to deduce the type of FUN here.
    Change the above line to:

    insert_sort<double, std::less<double> >(pdarr, sizeof(darr) /
    sizeof(double));

    > std::cout << "after insort sort:\n";
    > display(std::cout, pdarr, sizeof(darr) / sizeof(int));
    >
    > delete[] piarr;
    > delete[] pdarr;
    >
    > return 0;
    > }
    >
    > What's wrong??
    > Why the default arguement doesn't work??


    Because the compiler can't deduce the type of FUN using the default
    argument when it depends upon the type of another template parameter.

    > Thanks.


    Best regards,

    Tom
     
    Thomas Tutone, Nov 9, 2006
    #3
  4. Wayne Shu

    VJ Guest

    Thomas Tutone wrote:

    >>The code is below:
    >>#include <iostream>
    >>#include <functional>
    >>
    >>template <typename T, typename FUN>
    >>void insert_sort(T *arr, size_t size, FUN f = std::less<T>())
    >>{
    >> for( int j = 1; j < size; j++ ){
    >> type key = arr[j];

    >
    >
    > What is "type"? It's not defined.



    Yes, instead of type should put T


    >
    >
    >> int i = j - 1;
    >> while( i >= 0 && f(arr, key) ){
    >> arr[i+1] = arr;
    >> i = i - 1;
    >> }
    >> arr[i+1] = key;
    >> }
    >>}
    >>
    >>template <typename T>
    >>void display(std::eek:stream &out, const T *arr, size_t size)
    >>{
    >> out << "<";
    >> for(size_t i = 0; i < size; ++i){
    >> out << arr << ((i == size - 1) ? ">" : " ");
    >> }
    >>}
    >>
    >>int main()
    >>{
    >> const int iarr[] = { 9, 8, 56, 784, 2, 7, 89, 4 };
    >> const double darr[] = { 7.8, 89.2, 45.0, 44.0, 9.6, 78.4, 999.0 };
    >> int *piarr = new int[sizeof(iarr) / sizeof(int)];
    >> double *pdarr = new double[sizeof(darr) / sizeof(double)];
    >>
    >> std::cout << "before sort:\n";
    >> display(std::cout, iarr, sizeof(iarr) / sizeof(int));
    >>
    >> // test for insert sort
    >> memcpy(piarr, iarr, sizeof(iarr));
    >> insert_sort(piarr, sizeof(iarr) / sizeof(int));

    >
    >
    > There's no way for the compiler to deduce the type of FUN here. Change
    > the above line to:
    >
    > insert_sort<int, std::less<int> >(piarr, sizeof(iarr) /
    > sizeof(int));


    This gives next warning:

    taking address of temporary

    Anyone know a way to remove it?
     
    VJ, Nov 9, 2006
    #4
  5. Wayne Shu

    Jim Langston Guest

    "VJ" <> wrote in message
    news:eivlcn$gvn$...
    > Thomas Tutone wrote:
    >
    >>>The code is below:
    >>>#include <iostream>
    >>>#include <functional>
    >>>
    >>>template <typename T, typename FUN>
    >>>void insert_sort(T *arr, size_t size, FUN f = std::less<T>())
    >>>{
    >>> for( int j = 1; j < size; j++ ){
    >>> type key = arr[j];

    >>
    >>
    >> What is "type"? It's not defined.

    >
    >
    > Yes, instead of type should put T
    >
    >
    >>
    >>
    >>> int i = j - 1;
    >>> while( i >= 0 && f(arr, key) ){
    >>> arr[i+1] = arr;
    >>> i = i - 1;
    >>> }
    >>> arr[i+1] = key;
    >>> }
    >>>}
    >>>
    >>>template <typename T>
    >>>void display(std::eek:stream &out, const T *arr, size_t size)
    >>>{
    >>> out << "<";
    >>> for(size_t i = 0; i < size; ++i){
    >>> out << arr << ((i == size - 1) ? ">" : " ");
    >>> }
    >>>}
    >>>
    >>>int main()
    >>>{
    >>> const int iarr[] = { 9, 8, 56, 784, 2, 7, 89, 4 };
    >>> const double darr[] = { 7.8, 89.2, 45.0, 44.0, 9.6, 78.4, 999.0 };
    >>> int *piarr = new int[sizeof(iarr) / sizeof(int)];
    >>> double *pdarr = new double[sizeof(darr) / sizeof(double)];
    >>>
    >>> std::cout << "before sort:\n";
    >>> display(std::cout, iarr, sizeof(iarr) / sizeof(int));
    >>>
    >>> // test for insert sort
    >>> memcpy(piarr, iarr, sizeof(iarr));
    >>> insert_sort(piarr, sizeof(iarr) / sizeof(int));

    >>
    >>
    >> There's no way for the compiler to deduce the type of FUN here. Change
    >> the above line to:
    >>
    >> insert_sort<int, std::less<int> >(piarr, sizeof(iarr) /
    >> sizeof(int));

    >
    > This gives next warning:
    >
    > taking address of temporary
    >
    > Anyone know a way to remove it?


    sizeof( iarr[0] ) maybe?
     
    Jim Langston, Nov 9, 2006
    #5
  6. Wayne Shu

    Wayne Shu Guest

    "Thomas Tutone дµÀ£º
    "
    > Wayne Shu wrote:
    >
    > > Why this code can't be compiled??

    >
    > Because it's not legal C++.
    >
    > > The code is below:
    > > #include <iostream>
    > > #include <functional>
    > >
    > > template <typename T, typename FUN>
    > > void insert_sort(T *arr, size_t size, FUN f = std::less<T>())
    > > {
    > > for( int j = 1; j < size; j++ ){
    > > type key = arr[j];

    >
    > What is "type"? It's not defined.

    sorry, "type" should be "T", I forgot to modify it.

    >
    > > int i = j - 1;
    > > while( i >= 0 && f(arr, key) ){
    > > arr[i+1] = arr;
    > > i = i - 1;
    > > }
    > > arr[i+1] = key;
    > > }
    > > }
    > >
    > > template <typename T>
    > > void display(std::eek:stream &out, const T *arr, size_t size)
    > > {
    > > out << "<";
    > > for(size_t i = 0; i < size; ++i){
    > > out << arr << ((i == size - 1) ? ">" : " ");
    > > }
    > > }
    > >
    > > int main()
    > > {
    > > const int iarr[] = { 9, 8, 56, 784, 2, 7, 89, 4 };
    > > const double darr[] = { 7.8, 89.2, 45.0, 44.0, 9.6, 78.4, 999.0 };
    > > int *piarr = new int[sizeof(iarr) / sizeof(int)];
    > > double *pdarr = new double[sizeof(darr) / sizeof(double)];
    > >
    > > std::cout << "before sort:\n";
    > > display(std::cout, iarr, sizeof(iarr) / sizeof(int));
    > >
    > > // test for insert sort
    > > memcpy(piarr, iarr, sizeof(iarr));
    > > insert_sort(piarr, sizeof(iarr) / sizeof(int));

    >
    > There's no way for the compiler to deduce the type of FUN here. Change
    > the above line to:
    >
    > insert_sort<int, std::less<int> >(piarr, sizeof(iarr) /
    > sizeof(int));
    >
    > > std::cout << "after insort sort:\n";
    > > display(std::cout, piarr, sizeof(iarr) / sizeof(int));
    > >
    > > // test for insert sort
    > > memcpy(pdarr, darr, sizeof(darr));
    > > insert_sort(pdarr, sizeof(darr) / sizeof(double));

    >
    > Again, there's no way for the compiler to deduce the type of FUN here.
    > Change the above line to:
    >
    > insert_sort<double, std::less<double> >(pdarr, sizeof(darr) /
    > sizeof(double));
    >
    > > std::cout << "after insort sort:\n";
    > > display(std::cout, pdarr, sizeof(darr) / sizeof(int));
    > >
    > > delete[] piarr;
    > > delete[] pdarr;
    > >
    > > return 0;
    > > }
    > >
    > > What's wrong??
    > > Why the default arguement doesn't work??

    >
    > Because the compiler can't deduce the type of FUN using the default
    > argument when it depends upon the type of another template parameter.
    >

    If I want to the default argument work, how to change the code??

    > > Thanks.

    >
    > Best regards,
    >
    > Tom
     
    Wayne Shu, Nov 10, 2006
    #6
  7. Wayne Shu wrote:

    > "Thomas Tutone дµÀ£º


    > > Wayne Shu wrote:
    > >
    > > > Why this code can't be compiled??

    > >
    > > Because it's not legal C++.


    [snip]

    > > > What's wrong??
    > > > Why the default arguement doesn't work??


    > > Because the compiler can't deduce the type of FUN using the default
    > > argument when it depends upon the type of another template parameter.
    > >

    > If I want to the default argument work, how to change the code??


    I have no idea whether your code is correct, but the way to make the
    default argument work is to overload the template to have another
    version of insert_sort that only takes two arguments. Try this:

    #include <iostream>
    #include <functional>

    template <typename T, typename Fun>
    void insert_sort(T *arr, size_t size, Fun f)
    {
    for( int j = 1; j < size; j++ ){
    T key = arr[j];
    int i = j - 1;
    while( i >= 0 && f(arr, key) ) {
    arr[i+1] = arr;
    i = i - 1;
    }
    arr[i+1] = key;
    }
    }

    template <typename T>
    inline void insert_sort(T *arr, size_t size)
    {
    insert_sort(arr, size, std::less<T>());
    }


    template <typename T>
    void display(std::eek:stream &out, const T *arr, size_t size)
    {
    out << "<";
    for(size_t i = 0; i < size; ++i){
    out << arr << ((i == size - 1) ? ">" : " ");
    }
    }

    int main()
    {
    const int iarr[] = { 9, 8, 56, 784, 2, 7, 89, 4 };
    const double darr[] = { 7.8, 89.2, 45.0, 44.0, 9.6, 78.4, 999.0
    };
    int *piarr = new int[sizeof(iarr) / sizeof(int)];
    double *pdarr = new double[sizeof(darr) / sizeof(double)];

    std::cout << "before sort:\n";
    display(std::cout, iarr, sizeof(iarr) / sizeof(int));

    // test for insert sort
    memcpy(piarr, iarr, sizeof(iarr));
    insert_sort(piarr, sizeof(iarr) / sizeof(int));
    std::cout << "after insort sort:\n";
    display(std::cout, piarr, sizeof(iarr) / sizeof(int));

    // test for insert sort
    memcpy(pdarr, darr, sizeof(darr));
    insert_sort(pdarr, sizeof(darr) / sizeof(double));
    std::cout << "after insort sort:\n";
    display(std::cout, pdarr, sizeof(darr) / sizeof(int));

    delete[] piarr;
    delete[] pdarr;
    }

    Best regards,

    Tom
     
    Thomas Tutone, Nov 10, 2006
    #7
  8. Hello,

    Wayne Shu wrote:

    > template <typename T, typename FUN>
    > void insert_sort(T *arr, size_t size, FUN f = std::less<T>())


    > What's wrong??
    > Why the default arguement doesn't work??


    What you basically intended is a default template parameter. (You even
    wanted it to be deduced through a default argument to a function
    parameter.)

    template <typename T, typename FUN = std::less<T>>
    void insert_sort(T *arr, size_t size, FUN f = FUN())

    But this is clearly illegal, my compiler says:

    error: default template arguments may not be used in function templates

    This is state of the art in the current standard, and according to the
    book "C++ Templates" by Vandevoorde and Josuttis, it is being worked
    on. Currently, the template parameters of a function template must be
    deducible from the call expression.

    You can overload as T. Tutone suggested. The nice point is that this can
    be done uniformly with a few lines. If the standard gets extended to
    allow default parameters for function templates those trivial overloads
    may disappear again. I don't know whether this case can be really
    considered, because it could become hairy to mix template argument
    deduction, and function overload resolution that much.

    template <typename T, typename FUN>
    void insert_sort(T *arr, size_t size, FUN f)
    {...
    }

    template <typename T>
    void insert_sort(T *arr, size_t size)
    {
    insert_sort(arr, size, std::less<T>);
    }

    Bernd Strieder
     
    Bernd Strieder, Nov 10, 2006
    #8
  9. Wayne Shu

    Wayne Shu Guest

    thanks, I forgot that we can the trick of overload function
    "Bernd Strieder дµÀ£º
    "
    > Hello,
    >
    > Wayne Shu wrote:
    >
    > > template <typename T, typename FUN>
    > > void insert_sort(T *arr, size_t size, FUN f = std::less<T>())

    >
    > > What's wrong??
    > > Why the default arguement doesn't work??

    >
    > What you basically intended is a default template parameter. (You even
    > wanted it to be deduced through a default argument to a function
    > parameter.)
    >
    > template <typename T, typename FUN = std::less<T>>
    > void insert_sort(T *arr, size_t size, FUN f = FUN())
    >
    > But this is clearly illegal, my compiler says:
    >
    > error: default template arguments may not be used in function templates
    >
    > This is state of the art in the current standard, and according to the
    > book "C++ Templates" by Vandevoorde and Josuttis, it is being worked
    > on. Currently, the template parameters of a function template must be
    > deducible from the call expression.
    >
    > You can overload as T. Tutone suggested. The nice point is that this can
    > be done uniformly with a few lines. If the standard gets extended to
    > allow default parameters for function templates those trivial overloads
    > may disappear again. I don't know whether this case can be really
    > considered, because it could become hairy to mix template argument
    > deduction, and function overload resolution that much.
    >
    > template <typename T, typename FUN>
    > void insert_sort(T *arr, size_t size, FUN f)
    > {...
    > }
    >
    > template <typename T>
    > void insert_sort(T *arr, size_t size)
    > {
    > insert_sort(arr, size, std::less<T>);
    > }
    >
    > Bernd Strieder
     
    Wayne Shu, Nov 11, 2006
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Klaus Schneider
    Replies:
    1
    Views:
    562
    Rolf Magnus
    Dec 2, 2004
  2. Mr. SweatyFinger

    why why why why why

    Mr. SweatyFinger, Nov 28, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    921
    Mark Rae
    Dec 21, 2006
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,071
    Smokey Grindel
    Dec 2, 2006
  4. andrew
    Replies:
    11
    Views:
    526
    Marcus Kwok
    Jul 5, 2007
  5. lander
    Replies:
    5
    Views:
    607
    bruce barker
    Mar 5, 2008
Loading...

Share This Page