I am not sure if title makes sense.
let me explain what I want to do:
I have template constructor, the argument generally must be reference, but can be value in certain cases. Ultimately, I would like to have something like:
matrix_adapter(typename adaptable<T,A>::type);
where 开发者_如何学编程adaptable<T,A>::type
can either be value or reference defending on type of A.
I am not able to do so (template instantiation does not happen), and unsure why.
Right now, my solution is to enable/disable constructor using Sfinae:
matrix_adapter(A a, typename adaptable<T,A>::pass_by_value = 0)
however, that requires two constructors which are essentially the same.
Is it possible to do it using one generic constructor?
more code:
template<typename T>
struct adaptable<T, boost::detail::multi_array::const_sub_array<T, 2, const T*> >
{
typedef void* pass_by_value;
typedef boost::detail::multi_array::const_sub_array<T, 2, const T*> type;
static size_t size1(const type &A) { return A.shape()[0]; }
static size_t size2(const type &A) { return A.shape()[1]; }
static const T* data(const type &A) { return A.origin(); }
};
template<typename T, class L = ublas::column_major>
struct matrix_adapter
: ublas::matrix<T, L, ublas::array_adaptor<T> >
{
typedef ublas::array_adaptor<T> array_type;
typedef ublas::matrix<T, L, array_type> base;
matrix_adapter(size_t size1, size_t size2, T *data)
: base(size1, size2, array_type(size1*size2, pointer()))
{
initialize(data);
}
template<class A>
matrix_adapter(A a, typename adaptable<T,A>::pass_by_value = 0)
: base(adaptable<T,A>::size1(a),
adaptable<T,A>::size2(a),
array_type(adaptable<T,A>::size1(a)*
adaptable<T,A>::size2(a),
pointer()))
{
initialize(adaptable<T,A>::data(a));
}
template<class A>
matrix_adapter(A &a)
: base(adaptable<T,A>::size1(a),
adaptable<T,A>::size2(a),
array_type(adaptable<T,A>::size1(a)*
adaptable<T,A>::size2(a),
pointer()))
{
initialize(adaptable<T,A>::data(a));
}
Your constructor is itself a template, but with a signature of matrix_adapter(typename adaptable<T,A>::type)
the compiler cannot deduce the type of A
from the call.
By using SFINAE you enable the compiler to deduce A
from the first constructor argument, and then the second argument prevents one or other from being considered in the overload set.
I don't believe it is possible to eliminate either constructor.
精彩评论