我有一个名为Basis
的模板类,它的实例化如下:
Basis<std::function<sla::col<3>(const sla::col<2>&)>> basis;
并定义如下:
template<typename V>
struct Basis {
std::vector<V> vectors;
Basis()
{}
explicit Basis(std::vector<V>&& vectors)
: vectors(vectors)
{}
// if V+=V and V*=double are defined *** THE FOLLOWING LINE GENERATES THE COMPILER ERROR ***
template<typename T = std::remove_reference_t<decltype(std::declval<V&>() += (std::declval<V&>() *= double()))>>
V operator*(const std::vector<double>& coeffs) const {
V result = zero<V>();
if (coeffs.size() > vectors.size()) {
throw std::runtime_error("coeffs count exceeds basis vectors count");
}
for (size_t k = 0; k < coeffs.size(); k++) {
V term = vectors[k];
term *= coeffs[k];
result += term;
}
return result;
}
// alternative to operator* if V does not define += and *=
LinearCombination<V> linearCombination(const std::vector<double>& coeffs) const {
LinearCombination<V> result;
if (coeffs.size() > vectors.size()) {
throw std::runtime_error("coeffs count exceeds basis vectors count");
}
for (size_t k = 0; k < coeffs.size(); k++) {
result += typename LinearCombination<V>::Term{ coeffs[k], vectors[k] };
}
return result;
}
// if V(x) is defined
template<typename X>
auto operator()(X x) const -> Basis<std::remove_reference_t<decltype(std::declval<V>()(x))>> {
return Basis<std::remove_reference_t<decltype(std::declval<V>()(x))>>(util::transformation(vectors, [x](const V& v) {
return v(x);
}));
}
// if V[i] is defined
template<typename I>
auto operator[](I i) const -> Basis<std::remove_reference_t<decltype(std::declval<V>()[i])>> {
return Basis<std::remove_reference_t<decltype(std::declval<V>()[i])>>(util::transformation(vectors, [i](const V& v) {
return v[i];
}));
}
}
使用MSVC可以正常编译,但是使用GCC编译时会出现以下错误:
In instantiation of ‘struct Basis<std::function<sla::col<3>(const sla::col<2>&)> >’:
[LINE_NUMBER_OF_INSTANTIATION]: required from here
[LINE_NUMBER_OF_DECLARATION_OF_OPERATOR*=]: error: no match for ‘operator*=’ (operand types are ‘std::function<sla::col<3>(const sla::col<2>&)>’ and ‘double’)
template<typename T = std::remove_reference_t<decltype(std::declval<V&>() += (std::declval<V&>() *= double()))>>
鉴于Basis<std::function<sla::col<3>(const sla::col<2>&)>>::operator*
未定义,为什么GCC会实例化std::function<sla::col<3>(const sla::col<2>&)>::operator*=
?
错误消息是否暗示GCC认为basis.operator*()
正在某个地方被调用?
我只能找到对成员basis.operator()()
,basis.linearCombination()
的引用。但是,当我仅使用那些引用隔离代码时,问题就消失了。因此,由于无法确定问题的实际来源,因此我无法给出一个完整的例子来重现该问题。
我只是希望能找到可能导致问题发生的正确方向的任何指针。