模版元编程问题

adie20018u8 2007-02-03 10:29:32
如果利用模版元编程技术实现在编译器判断一个类型是否有支持某个函数操作?

比如 std::cout<<x 操作是否存在, print(x) 是否存在。

或者判断某个类型是否是一个类,这个类是否有某个成员函数。
...全文
383 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
healer_kx 2007-02-05
  • 打赏
  • 举报
回复
专门为了实现这个很容易。
taodm 2007-02-05
  • 打赏
  • 举报
回复
那得看你的评判标准是不是和我一样了。
www_adintr_com 2007-02-05
  • 打赏
  • 举报
回复
为每一个类特化一个版本还叫简单?
taodm 2007-02-05
  • 打赏
  • 举报
回复
您这个想法是好,但太复杂了。第一问解决比较难,第二问是可以的。看More Exectpional C++ Item 4
不过,你还是要求用户特化萃取类 来明白告诉你这些信息吧。简单才是美。
天堂里的死神 2007-02-03
  • 打赏
  • 举报
回复
如果利用模版元编程技术实现在编译器判断一个类型是否有支持某个函数操作?
________________________
这个,如果不支持会编译出错,所以没必要作。

www_adintr_com 2007-02-03
  • 打赏
  • 举报
回复
实现 is_cout 的一个办法如下,不过对基本类型好像不行,需要特殊处理一下:


class C{};
std::ostream& operator<<(std::ostream& ostr, const C& v)
{
return ostr;
}


namespace HelloWorld
{
struct big_size { char temp[111111]; };

template < typename X >
big_size operator<<(std::ostream&, const X&);

template <typename T>
struct is_cout
{
enum {
Result = sizeof(operator<<(std::cout, T())) != sizeof(big_size),
};
};
}

class A{};
class B{};

std::ostream& operator<<(std::ostream& ostr, const B& b)
{
return ostr;
}

int main()
{
printf("is_cout of A : %d\n", HelloWorld::is_cout<A>::Result);
printf("is_cout of B : %d\n", HelloWorld::is_cout<B>::Result);
printf("is_cout of C : %d\n", HelloWorld::is_cout<C>::Result);
printf("is_cout of int : %d\n", HelloWorld::is_cout<int>::Result);
}
adie20018u8 2007-02-03
  • 打赏
  • 举报
回复
1. 如何萃取? 能否给出
template <typename T>
struct is_cout
{
enum { Result = ... };
};
的实现方法?

如下这种对每一个类型一一特化的办法就免了:
template <typename T> struct is_cout { enum { Result = 0 }; };

template <> struct is_cout<int> { enum {Result = 1} ; };
template <> struct is_cout<char> { enum {Result = 1} ; };
...

2. 一个类如果不从另一个类派生的话,即使该类有另一个类的相同的方法也无法向它
转型的, 你给出的办法是行不通的。
sycnick 2007-02-03
  • 打赏
  • 举报
回复
是否支持 std::cout<<v 操作,就是类型萃取阿,你如果取出来是基本类型,那么就可以肯定支持std::cout<<v 操作

至于是否有一个叫 print() 的成员函数,你可以先定义一个纯虚的class,就一个print()方法。
然后使用类似如下的方式,判断是否能转换到该纯虚函数
template< typename U >
struct convertible_helper
{
static yes_type check( U );
static no_type REGEX_CDECL check(...);
};

template< typename T >
struct factory
{
static T& make();
};

template< typename T, typename U >
struct is_convertible
{
enum { value = (sizeof(convertible_helper<U>::check(factory<T>::make()))==sizeof(yes_type)) };
};
adie20018u8 2007-02-03
  • 打赏
  • 举报
回复
可能我没有说清楚,举个例子来说:

我想写一个模版函数来打印任意类型的对象

template <typename T>
void print(const T& v)
{
...
}

在实现的时候我首先想知道这个类型是否支持 std::cout<<v 操作, 如果支持则执行。 如果不支持再判断这个类是否有一个叫 print() 的成员函数,如果有则调用之。如果以上都不支持,则打印 "unknown type".

假设有两个元函数来完成这两个判断:

template <typename T>
struct is_cout // 是否可以 std::cout, 可以则 Result 为 1, 否则为 0
{
enum { Result = ... };
};

template <typename T> // 是否有 print 成员函数, 有 Result 为 1, 否则为 0
struct is_print
{
enum { Result = ... };
};

然后我的 print 模板函数就可以这样实现了:

template <int Type, typename T>
void print_imp(const T& v);

template <typename T>
void print(const T& v)
{
print_imp<is_cout<T>::Result * 2 + is_print<T>::Result >(v);
}

template <typename T>
void print_imp<2, T>(const T& v)
{
std::cout<<v;
}

template <typename T>
void print_imp<1, T>(const T& v)
{
v.print();
}

template <typename T>
void print_imp<0, T>(const T& v)
{
std::cout<<"Unknown Type.";
}

template <typename T>
void print_imp<3, T>(const T& v) // 即可 std::cout 又有 print 函数
{
v.print();
}

现在的问题是,上面的 is_cout 和 is_print 如何实现?
高人指教。
sycnick 2007-02-03
  • 打赏
  • 举报
回复
loki的类型萃取,可以实现你的要求
layject 2007-02-03
  • 打赏
  • 举报
回复
觉得可以用条件编程
如#ifdef
之类的语言

介绍一本书
候捷的《STL源码剖析里面》好像有介绍

64,650

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧