我在样式中有一个模板函数:
template <int Exponent> DERIVED_TYPE pow(TYPE const x);
Run Code Online (Sandbox Code Playgroud)
此函数在模板结构中作为友元函数内联定义:
template <ARGUMENTS>
struct unit {
typedef unit<ARGUMENTS> type;
....
template <int Exponent>
friend constexpr unit_pow_t<type, Exponent> pow(type const x) { ... }
};
Run Code Online (Sandbox Code Playgroud)
这是因为将具有单位的值与功率一起取决于该值必须改变单位.
当我尝试使用它省略Exponent时,我可以看到编译器考虑匹配的候选者:
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);
^
Run Code Online (Sandbox Code Playgroud)
到目前为止事情是预期的,模板可以看到,但当然需要指定Exponent.当我做的时候会发生意外的事情:
src/model/Tool.cpp:113:6: error: comparison between pointer and integer ('double (*)(double, double)' and 'int')
pow<3>(1._m);
~~~^~
Run Code Online (Sandbox Code Playgroud)
编译器将pow视为" double pow(double,double) " 的地址,并将<3解释为将函数指针与整数进行比较的意图.clang 3.4,3.6和GCC 5.2会出现问题.
我的问题是,我如何说服编译器<3>是模板参数列表?
UPDATE
我终于设法创建了一个最小的例子,对不完整的问题抱歉:
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;
};
Run Code Online (Sandbox Code Playgroud)
似乎没有看到战俘:
targs.cpp:11:2: error: use of undeclared identifier 'pow'
pow<2>(metre<1>{1});
^
Run Code Online (Sandbox Code Playgroud)
如果我包含cmath,我有与以前相同的诊断:
targs.cpp:13:5: error: comparison between pointer and integer ('double (*)(double, double)' and 'int')
pow<2>(metre<1>{1});
~~~^~
1 error generated.
Run Code Online (Sandbox Code Playgroud)
因此," 双重(双,双) "的存在只是掩盖了模板未被看到的问题.那么问题是,为什么编译器看不到pow <>()?
没有必要(也没有逻辑)friend template。使用免费函数:
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;
};
Run Code Online (Sandbox Code Playgroud)