I'm running into a problem with ambiguity with an Assignment partial specialization inside the inverse method of the full-pivot Householder decomposition of a dense matrix in the first release candidate for 3.3, 3.3.rc1. Here's a minimal example that produces the error we're getting compiling the Stan math library:
#include <Eigen/Dense>
int main() {
using Eigen::MatrixXd;
MatrixXd m(2, 2);
m << 1, 0, 0, 1;
Eigen::FullPivHouseholderQR<MatrixXd> hh
= m.fullPivHouseholderQr();
MatrixXd m_inv_transpose = hh.inverse();
}
Are we not using FullPivHouseholderQR the right way?
Here's the error I get using clang++ on Mac OS X (Apple LLVM version 7.0.2 (clang-700.1.81)):
temp2$ clang++ -isystem ~/cmdstan/stan/lib/stan_math/lib/eigen_3.3.rc1 fph.cpp
In file included from fph.cpp:1:
In file included from /Users/carp/cmdstan/stan/lib/stan_math/lib/eigen_3.3.rc1/Eigen/Dense:1:
In file included from /Users/carp/cmdstan/stan/lib/stan_math/lib/eigen_3.3.rc1/Eigen/Core:389:
/Users/carp/cmdstan/stan/lib/stan_math/lib/eigen_3.3.rc1/Eigen/src/Core/AssignEvaluator.h:813:3: error: ambiguous partial specializations
of 'Assignment, Eigen::Inverse > >, Eigen::internal::assign_op, Eigen::internal::Dense2Dense, void>'
Assignment::run(actualDst, src, func);
^
/Users/carp/cmdstan/stan/lib/stan_math/lib/eigen_3.3.rc1/Eigen/src/Core/PlainObjectBase.h:721:17: note: in instantiation of function
template specialization 'Eigen::internal::call_assignment_no_alias,
Eigen::Inverse > >, Eigen::internal::assign_op
>' requested here
internal::call_assignment_no_alias(this->derived(), other.derived(), internal::assign_op());
^
/Users/carp/cmdstan/stan/lib/stan_math/lib/eigen_3.3.rc1/Eigen/src/Core/PlainObjectBase.h:531:7: note: in instantiation of function
template specialization 'Eigen::PlainObjectBase
>::_set_noalias > > >' requested here
_set_noalias(other);
^
/Users/carp/cmdstan/stan/lib/stan_math/lib/eigen_3.3.rc1/Eigen/src/Core/Matrix.h:379:9: note: in instantiation of function template
specialization 'Eigen::PlainObjectBase
>::PlainObjectBase > > >' requested here
: Base(other.derived())
^
fph.cpp:9:30: note: in instantiation of function template specialization 'Eigen::Matrix::Matrix > > >' requested here
MatrixXd m_inv_transpose = hh.inverse();
^
/Users/carp/cmdstan/stan/lib/stan_math/lib/eigen_3.3.rc1/Eigen/src/Core/AssignEvaluator.h:851:8: note: partial specialization matches
[with DstXprType = Eigen::Matrix, SrcXprType =
Eigen::Inverse > >, Functor =
Eigen::internal::assign_op, Weak = void]
struct Assignment
^
/Users/carp/cmdstan/stan/lib/stan_math/lib/eigen_3.3.rc1/Eigen/src/LU/InverseImpl.h:290:8: note: partial specialization matches [with
DstXprType = Eigen::Matrix, XprType = Eigen::FullPivHouseholderQR >]
struct Assignment, internal::assign_op, Dense2Dense>
^
/Users/carp/cmdstan/stan/lib/stan_math/lib/eigen_3.3.rc1/Eigen/src/QR/FullPivHouseholderQR.h:579:8: note: partial specialization matches
[with DstXprType = Eigen::Matrix, MatrixType = Eigen::Matrix, Scalar = double]
struct Assignment >, internal::assign_op, Dense2Dense>
^
1 error generated.
Related
consider the following code:
#include <future>
#include <boost/optional.hpp>
struct S {
std::promise<int> p;
};
void f() {
boost::optional<S> o = std::move(S());
}
it fails to compile because somewhere deep inside boost::optional implementation it tries to use the copy constructor of S.
is there some way to overcome this and move the promise without copying it?
I tried to explicitly add a move constructor to S
S(S&& s): p(std::move(s.p)) {}
S() = default;
to no avail.
compiler error message:
In file included from /usr/include/boost/optional.hpp:15:0,
from /tmp/iotpromise.cpp:2:
/usr/include/boost/optional/optional.hpp: In instantiation of ‘void boost::optional_detail::optional_base<T>::construct(boost::optional_detail::optional_base<T>::argument_type) [with T = S; boost::optional_detail::optional_base<T>::argument_type = const S&]’:
/usr/include/boost/optional/optional.hpp:230:20: required from ‘boost::optional_detail::optional_base<T>::optional_base(boost::optional_detail::optional_base<T>::argument_type) [with T = S; boost::optional_detail::optional_base<T>::argument_type = const S&]’
/usr/include/boost/optional/optional.hpp:526:46: required from ‘boost::optional<T>::optional(boost::optional<T>::argument_type) [with T = S; boost::optional<T>::argument_type = const S&]’
/tmp/iotpromise.cpp:9:39: required from here
/usr/include/boost/optional/optional.hpp:346:8: error: use of deleted function ‘S::S(const S&)’
new (m_storage.address()) internal_type(val) ;
^
/tmp/iotpromise.cpp:4:8: note: ‘S::S(const S&)’ is implicitly deleted because the default definition would be ill-formed:
struct S {
^
/tmp/iotpromise.cpp:4:8: error: use of deleted function ‘std::promise<_Res>::promise(const std::promise<_Res>&) [with _Res = int]’
In file included from /tmp/iotpromise.cpp:1:0:
/usr/include/c++/4.9/future:977:7: note: declared here
promise(const promise&) = delete;
^
Using Boost 1.55.0, GCC 6.3
The following code doesn't compile, but I don't found the error (I don't unsderstand the message error).
My basic template type, 'int_mod_N', is an integer from 0 to 'N', an integer module 'N' (to represent elements of a cyclic group). This is very easy and I have constructed a library of integers represented in radix 'B', where the digits are of 'int_mod_N', and the integer is represented as 'std::basic_strings< int_mod_N >'. It works.
The problematic thing is the type I need to represent elements of a cartesian product of 'n' sets, for each of them integers module a const integer 'N_i'.
Mathematically, I want to represent elements of Z_Nn x ... x Z_N1, only the additive group.
The next code don't compile.
#include <tuple>
#include "int_mod_N_t.hpp"
template<
unsigned N_n,unsigned ... N_nm1
>
struct elem_set_t :
public
decltype(
std::tuple_cat(
std::tuple< int_mod_N_t<N_n> >{},
elem_set_t< N_nm1 ... >{}
)
)
{};
template<unsigned N_n,unsigned N_nm1>
struct elem_set_t<N_n,N_nm1> :
public
std::tuple<
int_mod_N_t<N_n> ,
int_mod_N_t<N_nm1>
>
{};
template<unsigned N_n>
struct elem_set_t<N_n> :
public
std::tuple<
int_mod_N_t<N_n>
>
{};
The error message of compiler (g++ 7.2.0), is
In file included from /tuplas_y_tipos/main.cpp:3:0:
/tuplas_y_tipos/elem_set_t.hpp: In instantiation of 'struct
elem_set_t<2, 2, 2>': /tuplas_y_tipos/main.cpp:8:20: required from
here /tuplas_y_tipos/elem_set_t.hpp:10:21: error: no matching function
for call to 'tuple_cat(std::tuple >, elem_set_t<2, 2>)'
std::tuple_cat(
~~~~~~~~~~~~~~^
std::tuple< int_mod_N_t >{},
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
elem_set_t< N_nm1 ... >{}
~~~~~~~~~~~~~~~~~~~~~~~~~
)
~ In file included from /tuplas_y_tipos/elem_set_t.hpp:1:0,
from /tuplas_y_tipos/main.cpp:3: c:\mingw\include\c++\7.2.0\tuple:1575:5: note: candidate:
template constexpr typename
std::__tuple_cat_result<_Tpls ...>::__type std::tuple_cat(_Tpls&& ...)
tuple_cat(_Tpls&&... __tpls)
^~~~~~~~~ c:\mingw\include\c++\7.2.0\tuple:1575:5: note: template argument deduction/substitution failed:
c:\mingw\include\c++\7.2.0\tuple:1572:31: error: no type named 'type'
in 'struct std::enable_if' template
elem_set_t<2,2,2> elem;
^~~~ make.exe[1]: * [tuplas_y_tipos.mk:97: Debug/main.cpp.o] Error 1 make.exe: * [Makefile:5: All] Error 2
make.exe[1]: Leaving directory '/tuplas_y_tipos'
====1 errors, 6 warnings====
I don't recommend inheriting from std::tuple at all, and for this, you don't need to.
template <unsigned ... N_ns>
using elem_set_t = std::tuple<int_mod_N_t<N_ns>...>;
If you have some methods in mind, you should have a tuple data member, not base class
template <unsigned ... N_ns>
struct elem_set_t
{
std::tuple<int_mod_N_t<N_ns>...> data;
// other members
}
In a template class I am working on, I want to check a precondition that a std::chrono::duration is positive, but my compiler complains that it can not instantiate the needed operator< template.
Here is a minimal example (not my original container) of the problem:
#include <chrono>
#include <cassert>
#undef NDEBUG
template< typename VALUE >
class Container final
{
public:
using Interval = std::chrono::duration< unsigned int >;
Container(const Interval interval_):
interval(interval_),
value(0)
{
assert(Interval::zero < interval_);
}
private:
Interval interval;
VALUE value;
};
template class Container< unsigned int >;
The compiler complains about the assert statement, thus:
In file included from /usr/include/c++/6/cassert:44:0,
from main.cpp:2:
main.cpp: In constructor ‘Container<VALUE>::Container(Container<VALUE>::Interval)’:
main.cpp:15:29: error: no match for ‘operator<’ (operand types are ‘std::chrono::duration<unsigned int>()’ and ‘const Interval {aka const std::chrono::duration<unsigned int>}’)
assert(Interval::zero < interval_);
~~~~~~~~~~~~~~~^~~
In file included from main.cpp:1:0:
/usr/include/c++/6/chrono:668:7: note: candidate: template<class _Clock, class _Dur1, class _Dur2> constexpr bool std::chrono::operator<(const std::chrono::time_point<_Clock, _Duration1>&, const std::chrono::time_point<_Clock, _Duration2>&)
operator<(const time_point<_Clock, _Dur1>& __lhs,
^~~~~~~~
/usr/include/c++/6/chrono:668:7: note: template argument deduction/substitution failed:
In file included from /usr/include/c++/6/cassert:44:0,
from main.cpp:2:
main.cpp:15:31: note: mismatched types ‘const std::chrono::time_point<_Clock, _Duration1>’ and ‘std::chrono::duration<unsigned int>()’
assert(Interval::zero < interval_);
^
In file included from main.cpp:1:0:
/usr/include/c++/6/chrono:489:7: note: candidate: template<class _Rep1, class _Period1, class _Rep2, class _Period2> constexpr bool std::chrono::operator<(const std::chrono::duration<_Rep1, _Period1>&, const std::chrono::duration<_Rep2, _Period2>&)
operator<(const duration<_Rep1, _Period1>& __lhs,
^~~~~~~~
/usr/include/c++/6/chrono:489:7: note: template argument deduction/substitution failed:
In file included from /usr/include/c++/6/cassert:44:0,
from main.cpp:2:
main.cpp:15:31: note: mismatched types ‘const std::chrono::duration<_Rep1, _Period1>’ and ‘std::chrono::duration<unsigned int>()’
assert(Interval::zero < interval_);
What have I done wrong?
Or is this a compiler bug? My compiler is g++ (Debian 6.3.0-18+deb9u1) 6.3.0 2017051, on Debian 6.
Try with Interval::zero(). Interval::zero is a function, so you are comparing a duration with a function.
As a side note, I would suggest to make your Interval argument in the constructor a template, so that you can accept other duragion scales (seconds, ms, us, etc.)
template < typename Interval2 >
explicit Container(const Interval2 interval_):
interval(interval_),
value(0)
{
assert(Interval2::zero() < interval_);
}
The std::chrono::duration constructor will adapt the tick count transparently, following both Period parameter types.
I don't understand why clang will not compile the following code but gcc does. No args or more than one arg to tuple works, a single arg does not.
#include <tuple>
int main(int , char *[])
{
// fails
std::tuple<int> a;
// works
std::tuple<> b;
std::tuple<int,int> c;
return 0;
}
The clang error
$ clang++ -std=c++14 tuple.cpp
In file included from tuple.cpp:1:
/usr/lib/gcc/x86_64-redhat-linux/6.1.1/../../../../include/c++/6.1.1/tuple:483:62: error: pack
expansion contains parameter packs '_Elements' and '_UElements' that have different lengths
(1 vs. 0)
return __and_<is_constructible<_Elements, _UElements&&>...>::value;
~~~~~~~~~ ~~~~~~~~~~ ^
/usr/lib/gcc/x86_64-redhat-linux/6.1.1/../../../../include/c++/6.1.1/tuple:631:21: note: in
instantiation of function template specialization 'std::_TC<true,
int>::_MoveConstructibleTuple<>' requested here
_MoveConstructibleTuple<_UElements...>()
^
/usr/lib/gcc/x86_64-redhat-linux/6.1.1/../../../../include/c++/6.1.1/tuple:636:19: note: while
substituting prior template arguments into non-type template parameter [with _UElements = <>]
constexpr tuple(_UElements&&... __elements)
^~~~~
tuple.cpp:5:21: note: while substituting deduced template arguments into function template 'tuple'
[with _UElements = <>, $1 = (no value)]
std::tuple<int> a;
^
In file included from tuple.cpp:1:
/usr/lib/gcc/x86_64-redhat-linux/6.1.1/../../../../include/c++/6.1.1/tuple:489:60: error: pack
expansion contains parameter packs '_UElements' and '_Elements' that have different lengths
(0 vs. 1)
return __and_<is_convertible<_UElements&&, _Elements>...>::value;
~~~~~~~~~~ ~~~~~~~~~ ^
/usr/lib/gcc/x86_64-redhat-linux/6.1.1/../../../../include/c++/6.1.1/tuple:633:21: note: in
instantiation of function template specialization 'std::_TC<true,
int>::_ImplicitlyMoveConvertibleTuple<>' requested here
_ImplicitlyMoveConvertibleTuple<_UElements...>()
^
/usr/lib/gcc/x86_64-redhat-linux/6.1.1/../../../../include/c++/6.1.1/tuple:636:19: note: while
substituting prior template arguments into non-type template parameter [with _UElements = <>]
constexpr tuple(_UElements&&... __elements)
^~~~~
tuple.cpp:5:21: note: while substituting deduced template arguments into function template 'tuple'
[with _UElements = <>, $1 = (no value)]
std::tuple<int> a;
^
2 errors generated.
While looking at Thread and interfaces C++, I noticed something a little strange with my Clang.
I have c++ --version output of
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.3.0
Thread model: posix
Compiling the following
#include <thread>
class Foo {
public:
void operator()() { }
};
int main() {
Foo *foo = new Foo();
std::thread t(foo);
t.join();
delete foo;
}
with c++ thread.cpp yields the following sensible error:
In file included from thread.cpp:1:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:369:5: error: called object type 'Foo *' is not a function or
function pointer
(*__p)();
^~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:377:42: note: in instantiation of function template
specialization 'std::__1::__thread_proxy<Foo *>' requested here
int __ec = pthread_create(&__t_, 0, &__thread_proxy<_Fp>, __p.get());
^
thread.cpp:10:17: note: in instantiation of function template specialization 'std::__1::thread::thread<Foo *>' requested here
std::thread t(foo);
^
1 error generated.
Total sense - Foo * isn't a function pointer.
But, compiling it with c++ -std=c++11 thread.cpp gives this cryptic error:
In file included from thread.cpp:1:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:332:5: error: attempt to use a deleted function
__invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:342:5: note: in instantiation of function template
specialization 'std::__1::__thread_execute<Foo *>' requested here
__thread_execute(*__p, _Index());
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:354:42: note: in instantiation of function template
specialization 'std::__1::__thread_proxy<std::__1::tuple<Foo *> >' requested here
int __ec = pthread_create(&__t_, 0, &__thread_proxy<_Gp>, __p.get());
^
thread.cpp:10:17: note: in instantiation of function template specialization 'std::__1::thread::thread<Foo *&, void>' requested here
std::thread t(foo);
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/type_traits:1027:5: note: '~__nat' has been explicitly marked
deleted here
~__nat() = delete;
^
1 error generated.
What's causing this weird error message about a deleted destructor? Should I consider it a bug in Clang to have such an odd message?
Your actual error message is the same in the two cases: whatever template is used to implement std::thread, it cannot be specialized for Foo*.
~__nat() = delete; is only a random difference between the old and new standard, one of the uninteresting things that fail because of the type error.