我在样式中有一个模板函数:
template <int Exponent> DERIVED_TYPE pow(TYPE const x);
此函数作为友元函数在模板结构中内联定义:
template <ARGUMENTS>
struct unit {
typedef unit<ARGUMENTS> type;
....
template <int Exponent>
friend constexpr unit_pow_t<type, Exponent> pow(type const x) { ... }
};
这是因为取一个带有单位的值的幂必须随着值的变化而改变单位。
当我尝试使用它时省略指数,我可以看到编译器考虑匹配的候选对象:
src/model/Tool.cpp:113:3: error: no matching function for call to 'pow'
pow(1._m);
^~~
src/model/../units/Units.hpp:2266:46: note: candidate template ignored: couldn't infer template argument 'Exponent'
friend constexpr unit_pow_t<type, Exponent> pow(type const x) {
^
/usr/include/math.h:255:8: note: candidate function not viable: requires 2 arguments, but 1 was provided
double pow(double, double);
^
到目前为止一切都如预期的那样,看到了模板,但是当然需要指定 Exponent。但是,当我这样做时,发生了意想不到的事情:
src/model/Tool.cpp:113:6: error: comparison between pointer and integer ('double (*)(double, double)' and 'int')
pow<3>(1._m);
~~~^~
编译器将 pow 视为“double pow(double, double)”的地址,并将 <3 解释为比较的意图带有整数的函数指针。 clang 3.4、3.6 和 GCC 5.2 会出现此问题。
我的问题是,如何让编译器相信 <3> 是模板参数列表?
更新
我终于设法创建了一个最小的示例,对于不完整的问题感到抱歉:
template <int Exp>
struct metre {
double value;
template <int Exponent>
friend constexpr metre<Exp * Exponent> pow(metre<Exp> const x) {
return {0};
}
};
int main() {
pow<2>(metre<1>{1});
return 0;
};
它似乎没有看到 pow:
targs.cpp:11:2: error: use of undeclared identifier 'pow'
pow<2>(metre<1>{1});
^
如果我包含 cmath,我将得到与以前相同的诊断:
targs.cpp:13:5: error: comparison between pointer and integer ('double (*)(double, double)' and 'int')
pow<2>(metre<1>{1});
~~~^~
1 error generated.
所以“double pow(double, double)”的存在只是掩盖了模板未被看到的问题。那么问题是,为什么编译器看不到 pow<>()?
最佳答案
friend 模板
没有必要(也没有逻辑)。使用免费功能:
template <int Exp>
struct metre {
double value;
};
template<int B, int A>
constexpr auto pow(metre<A> const x) -> metre<A*B>
{
return metre<A*B>{x.value};
}
int main() {
metre<2> result = pow<2>(metre<1>{1});
return 0;
};
关于c++ - 编译器错误地将模板参数列表用于 < 比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34198004/