简体   繁体   English

如何在模板结构中使用包装的typedef修复c ++编译

[英]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是依赖上下文中从intu_type的映射。

You need a map from u_type to int in order for type deduction to work. 您需要一个从u_typeint的映射,以便进行类型推导。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM