[英]How do I fix c++ compile with wrapped typedef in a template structure
This code will fail with error message (line numbers are off). 此代码将失败并显示错误消息(行号已关闭)。 How do I fix this (keeping same intent)?
我该如何解决这个问题(保持同样的意图)?
g++ -o c_test c_test.cpp
g ++ -o c_test c_test.cpp
c_test.cpp: In function 'int main(int, char**)': c_test.cpp:在函数'int main(int,char **)'中:
c_test.cpp:28:18: error: no matching function for call to 'wcalc(CWrapped<5>::u_type&)' c_test.cpp:28:18:错误:没有匹配函数来调用'wcalc(CWrapped <5> :: u_type&)'
c_test.cpp:28:18: note: candidate is: c_test.cpp:28:18:注意:候选人是:
c_test.cpp:17:58: note: template int wcalc(typename CWrapped::u_type) c_test.cpp:17:58:注意:template int wcalc(typename CWrapped :: u_type)
The wrapped type is passed to both "calc" and "wcalc" function, but the 2nd one fails. 包装类型传递给“calc”和“wcalc”函数,但第二个失败。 I want to be able to wrap the types so I can use a compile-time define to specify different types but still use the same wrapped function
我希望能够包装类型,以便我可以使用编译时定义来指定不同的类型,但仍然使用相同的包装函数
// Example template class
template <int T_B>
class m_int {
public:
int x;
m_int() { x = T_B; }
int to_int() { return(x); }
};
// Desired Typedef wrap
template <int T_BITS> struct CWrapped {
typedef m_int<T_BITS> u_type;
};
// This is ok, no wrapping
template <int T_BITS> int calc(m_int<T_BITS> x) {
return(x.to_int());
}
// This fails when instantiated
template <int T> int wcalc(typename CWrapped<T>::u_type x) {
return(x.to_int());
}
int main(int argc, char* argv[]) {
CWrapped<5>::u_type s;
int x = calc(s);
int y = wcalc(s);
return(0);
}
From the C++11 Standard, paragraph 14.8.2.5/16 来自C ++ 11标准,第14.8.2.5/16段
"If, in the declaration of a function template with a non-type template parameter, the non-type template parameter is used in a subexpression in the function parameter list, the expression is a non-deduced context as specified above. Example:" “如果在具有非类型模板参数的函数模板的声明中,在函数参数列表的子表达式中使用非类型模板参数,则表达式是如上所述的非推导上下文 。示例:”
template <int i> class A { / ... / };
template <int i> void g(A<i+1>);
template <int i> void f(A<i>, A<i+1>);
void k() {
A<1> a1;
A<2> a2;
g(a1); // error: deduction fails for expression i+1
g<0>(a1); // OK
f(a1, a2); // OK
}
"Note: Template parameters do not participate in template argument deduction if they are used only in non-deduced contexts . For example:" “注意: 如果模板参数仅在非推断的上下文中使用,则模板参数不参与模板参数推断 。例如:”
template<int i, typename T>
T deduce(typename A<T>::X x, // T is not deduced hereT t, // but T is deduced here
typename B<i>::Y y); // i is not deduced here
A<int> a;
B<77> b;
int x = deduce<77>(a.xm, 62, b.ym);
// T is deduced to be int, a.xm must be convertible to
// A<int>::X
// i is explicitly specified to be 77, b.ym must be convertible
// to B<77>::Y
Because of the above, your non-type template parameter T
cannot be deduced: you have to provided it explicitly: 由于上述原因,您的非类型模板参数
T
无法推断:您必须明确提供它:
int main(int argc, char* argv[]) {
CWrapped<5>::u_type s;
int x = calc(s);
int y = wcalc<5>(s); // Template argument 5 cannot be deduced!
return(0);
}
Also see this related link: C++, template argument can not be deduced (courtesy of @NateKohl) 另请参阅此相关链接: C ++,模板参数无法推断 (由@NateKohl提供)
Your problem is that CWrapped
is a map from int
to u_type
in a dependent context. 您的问题是
CWrapped
是依赖上下文中从int
到u_type
的映射。
You need a map from u_type
to int
in order for type deduction to work. 您需要一个从
u_type
到int
的映射,以便进行类型推导。
Template type deduction is simple pattern matching, it doesn't invert arbitrary template constructs. 模板类型推导是简单的模式匹配,它不会反转任意模板结构。
As an example, here is how you can extract which CWrapped
would resolve to T
: 例如,以下是如何提取哪个
CWrapped
将解析为T
:
template<typename T>
struct GetWrapped;
template<int N>
struct GetWrapped< m_int<N> > {
typedef CWrapped< N > type;
};
template <int T> int wcalc(T const& x) {
typedef typename GetWrapped<T>::type CWrappedType; // assuming you need it for something
return(x.to_int());
}
and here is how you can only accept T
for which there is such a mapping at overload resolution: 以下是如何只接受在重载分辨率下存在这种映射的
T
:
#include <type_traits>
template <int T> auto wcalc(T const& x)->typename std::enable_if< sizeof(typename GetWrapped<T>::type), int>::type {
return(x.to_int());
}
which uses SFINAE and C++11 features to check that GetWrapped<T>
is a valid construct. 它使用SFINAE和C ++ 11功能来检查
GetWrapped<T>
是否是有效的构造。
Now, this is probably an XY question, as in you asked X but you really needed to know Y. I'm hoping one of the above will help. 现在,这可能是一个XY问题,就像你问X但你真的需要知道Y.我希望上面的一个会有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.