$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
From: Thomas A. Seidel (thomas.seidel_at_[hidden])
Date: 2005-01-13 08:07:42
Hello everybody,
I wrote 2 simple template functions for printing the content of arrays which 
model boost::multi_array.
Template functions are necessary to be independent of the exact array type
(multi_array_ref, subarrays, array_views and so on), dimension and element 
type.
 
Here is the corresponding code snippet:
-------------------------------------------------------
#include <cstddef>
#include <iostream>
#include <string>
#include <boost/multi_array.hpp>
 
template <typename T, std::size_t Dim, template <typename, std::size_t> class 
ArrayType> 
std::ostream& print(const ArrayType<T, Dim>& ma, std::ostream& os);
template <typename T, template <typename, std::size_t> class ArrayType> 
std::ostream& print(const ArrayType<T, 1>& ma, std::ostream& os);
template <typename T, template <typename, std::size_t> class ArrayType> 
inline std::ostream& print(const ArrayType<T, 1>& ma, std::ostream& os)
{
    os << "| ";
    typename boost::multi_array<T, 1>::size_type ma_size = ma.size();
    for (typename boost::multi_array<T, 1>::size_type i = 0 ; i < ma_size; 
i++) 
        os << ma[i] << ' ';
    return os;
}
template <typename T, std::size_t Dim, template <typename, std::size_t> class 
ArrayType> 
inline std::ostream& print(const ArrayType<T, Dim>& ma, std::ostream& os)
{
    os << std::string(Dim, '|') << ' ';
    typename boost::multi_array<T, Dim>::size_type ma_size = ma.size();
    for (typename boost::multi_array<T, Dim>::size_type i = 0 ; i < ma_size; 
i++) { 
        typename ArrayType<T, Dim>::const_reference row = ma[i];
        print(row, os);
    }
    return os;
}
int main(int argc, char** argv)
{
    boost::multi_array<unsigned int, 3> test(boost::extents[4][4][4]);
    for (unsigned int i = 0; i < 4; i++)
        for (unsigned int j = 0; j < 4; j++)
            for (unsigned int k = 0; k < 4; k++)
                test[i][j][k] = k;
    print(test, std::cout);
    std::cout << std::endl;
    print(test[0], std::cout);
    std::cout << std::endl;
    return 0;
};
-------------------------------------------------------
The code compiles fine under Linux (Suse 9.1, gcc3.3.3) and upon execution 
produces the following (expected) output:
||| || | 0 1 2 3 | 0 1 2 3 | 0 1 2 3 | 0 1 2 3 || | 0 1 2 3 | 0 1 2 3 | 0 1 2 
3 | 0 1 2 3 || | 0 1 2 3 | 0 1 2 3 | 0 1 2 3 | 0 1 2 3 || | 0 1 2 3 | 0 1 2 3 
| 0 1 2 3 | 0 1 2 3
|| | 0 1 2 3 | 0 1 2 3 | 0 1 2 3 | 0 1 2 3
However, compiling the above code with VC7.1 produces 5 errors caused by the 
wrong deduction of the template parameters (the corresponding build-log is 
attached - unfortunately only in german language because I do not have an 
english VC version available, but its highly technical stuff anyway).
VC7 always deduces the 'ArrayType'-type for the template 
function wrong. The type VC7 uses for an instantiation is the direct base 
class (e.g. multi_array_ref instead of multi_array) instead of the actual 
argument type and in the end tries to call nonexistent member-functions and 
constructors. 
A search in the microsoft compiler-documentation didn't reveal a solution for 
my problem. 
   
So, is this a known bug/error/problem of VC7 and does anybody know an elegant 
workaround????
Thanks in advance!!
Regards,
Thomas