I'm having some trouble in initializing a boost histogram axis. The following appears to cause a mismatch between the type of the array and iterator vs pointer to first element. And insights/suggestions would be appreciated. thanks.
#include <iostream>
#include <array>
#include <boost/histogram/axis.hpp>
template<class C, const C& array_>
class Foo {
protected:
typedef boost::histogram::axis::variable<> VaxisType;
inline static VaxisType axis_{array_};
std::array<unsigned char, array_.size()> bins_;
public:
Foo() { }
};
template<class C, const C& array_>
class Bar : public Foo<C, array_> {
public:
using Base_Type = Foo<C, array_>;
Bar() : Base_Type{} { }
auto idx(double x) { return Base_Type::axis_.index(x); }
};
template<class Base = float>
class FS {
private:
static const unsigned nbins = 3;
typedef std::array<double, nbins> AType;
static constexpr AType bdrs{2.0, 3.0, 4.0};
Bar<AType, bdrs> blah;
public:
FS() : blah{} { }
auto idx(double x) { return blah.idx(x); }
};
int
main()
{
FS x1;
std::cout << x1.idx(3.5) << "\n";
return 0;
}
The error message generated is quite long (because of attempted template matching), but the essence of it is as follows:
% g++ -std=c++17 -o boost_no_workie-2{,.cc}
In file included from /usr/include/boost/histogram/axis.hpp:13,
from boost_no_workie-2.cc:4:
/usr/include/boost/histogram/axis/variable.hpp: In instantiation of ‘boost::histogram::axis::variable<Value, MetaData, Options, Allocator>::variable(It, It, boost::histogram::axis::variable<Value, MetaData, Options, Allocator>::metadata_type, boost::histogram::axis::variable<Value, MetaData, Options, Allocator>::allocator_type) [with It = const std::array<double, 3>*; <template-parameter-2-2> = boost::histogram::detail::requires_iterator<const std::array<double, 3>*, void>; Value = double; MetaData = boost::use_default; Options = boost::use_default; Allocator = std::allocator<double>; boost::histogram::axis::variable<Value, MetaData, Options, Allocator>::metadata_type = std::__cxx11::basic_string<char>; boost::histogram::axis::variable<Value, MetaData, Options, Allocator>::allocator_type = std::allocator<double>]’:
/usr/include/boost/histogram/axis/variable.hpp:122:77: required from ‘boost::histogram::axis::variable<Value, MetaData, Options, Allocator>::variable(std::initializer_list<_Up>, boost::histogram::axis::variable<Value, MetaData, Options, Allocator>::metadata_type, boost::histogram::axis::variable<Value, MetaData, Options, Allocator>::allocator_type) [with U = std::array<double, 3>; Value = double; MetaData = boost::use_default; Options = boost::use_default; Allocator = std::allocator<double>; boost::histogram::axis::variable<Value, MetaData, Options, Allocator>::metadata_type = std::__cxx11::basic_string<char>; boost::histogram::axis::variable<Value, MetaData, Options, Allocator>::allocator_type = std::allocator<double>]’
boost_no_workie-2.cc:10:28: required from ‘Foo<std::array<double, 3>, FS<float>::bdrs>::VaxisType Foo<std::array<double, 3>, FS<float>::bdrs>::axis_’
boost_no_workie-2.cc:22:47: required from ‘auto Bar<C, array_>::idx(double) [with C = std::array<double, 3>; const C& array_ = FS<float>::bdrs]’
boost_no_workie-2.cc:34:40: required from ‘auto FS<Base>::idx(double) [with Base = float]’
boost_no_workie-2.cc:41:25: required from here
/usr/include/boost/histogram/axis/variable.hpp:95:18: error: no match for ‘operator<=’ (operand types are ‘const std::array<double, 3>’ and ‘__gnu_cxx::__alloc_traits<std::allocator<double>, double>::value_type’ {aka ‘double’})
95 | if (*begin <= v.back())
... skip ...
/usr/include/boost/histogram/axis/variable.hpp:93:5: required from ‘boost::histogram::axis::variable<Value, MetaData, Options, Allocator>::variable(It, It, boost::histogram::axis::variable<Value, MetaData, Options, Allocator>::metadata_type, boost::histogram::axis::variable<Value, MetaData, Options, Allocator>::allocator_type) [with It = const std::array<double, 3>*; <template-parameter-2-2> = boost::histogram::detail::requires_iterator<const std::array<double, 3>*, void>; Value = double; MetaData = boost::use_default; Options = boost::use_default; Allocator = std::allocator<double>; boost::histogram::axis::variable<Value, MetaData, Options, Allocator>::metadata_type = std::__cxx11::basic_string<char>; boost::histogram::axis::variable<Value, MetaData, Options, Allocator>::allocator_type = std::allocator<double>]’
/usr/include/boost/histogram/axis/variable.hpp:122:77: required from ‘boost::histogram::axis::variable<Value, MetaData, Options, Allocator>::variable(std::initializer_list<_Up>, boost::histogram::axis::variable<Value, MetaData, Options, Allocator>::metadata_type, boost::histogram::axis::variable<Value, MetaData, Options, Allocator>::allocator_type) [with U = std::array<double, 3>; Value = double; MetaData = boost::use_default; Options = boost::use_default; Allocator = std::allocator<double>; boost::histogram::axis::variable<Value, MetaData, Options, Allocator>::metadata_type = std::__cxx11::basic_string<char>; boost::histogram::axis::variable<Value, MetaData, Options, Allocator>::allocator_type = std::allocator<double>]’
boost_no_workie-2.cc:10:28: required from ‘Foo<std::array<double, 3>, FS<float>::bdrs>::VaxisType Foo<std::array<double, 3>, FS<float>::bdrs>::axis_’
boost_no_workie-2.cc:22:47: required from ‘auto Bar<C, array_>::idx(double) [with C = std::array<double, 3>; const C& array_ = FS<float>::bdrs]’
boost_no_workie-2.cc:34:40: required from ‘auto FS<Base>::idx(double) [with Base = float]’
boost_no_workie-2.cc:41:25: required from here
/usr/include/c++/9/ext/new_allocator.h:145:20: error: cannot convert ‘const std::array<double, 3>’ to ‘double’ in initialization
145 | noexcept(noexcept(::new((void *)__p)
| ^~~~~~~~~~~~~~~~~~
146 | _Up(std::forward<_Args>(__args)...)))
Interesting. Compiling your sample gave me ICE on GCC 10 (which is always a compiler bug).
I started reducing till it did compile. I used c++17 auto non-type template arguments for simplicity :
#include <array>
#include <fmt/ranges.h>
template <auto const& array_> struct Foo {
static constexpr int N = array_.size();
};
template <auto const& array_> struct Bar : Foo<array_> {
using Base_Type = Foo<array_>;
};
struct FS {
static const unsigned nbins = 3;
static constexpr std::array<double, nbins> bdrs{2.0, 3.0, 4.0};
Bar<bdrs> blah;
};
int main() {
FS x1;
fmt::print(FMT_STRING("{}: {}\n"), x1.blah.N, x1.bdrs);
}
Prints
3: {2.0, 3.0, 4.0}
(with excellent codegen as expected).
Perhaps we can take it from here, to find where the problem is reintroduced. (Will be back after family things).
It's the template on FS<> that trips:
I thought it might have been the template argument deduction, but it isn't.
Also ICES: https://godbolt.org/z/hxMWPj
All in all I think this should be reported. CC trunk gives a more info should you chose to report: https://godbolt.org/z/489a5z - also consider using Creduce to minimize further
Interestingly things get unstuck when you use the template argument on FS. (This gives me a hunch it still involves the argument deduction machinery).
FIXED: https://godbolt.org/z/TWsas6
template <typename F>
struct FS {
static const unsigned nbins = 3;
static constexpr std::array<F, nbins> bdrs{2.0, 3.0, 4.0};
Bar<bdrs> blah;
};
int main() {
FS<float> x1;
fmt::print(FMT_STRING("{}: {}\n"), x1.blah.N, x1.bdrs);
}
Substituting back into your original sample leads to different compilation errors, which seem to be "normal" Boost Histogram type errors, so I'll leave that for you:
https://godbolt.org/z/9Tx3n3 (same error coming from your exact code with only the crucial changes: https://godbolt.org/z/sMMcWT
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.