C++ 引用的模板类型推断
我一直在使用带有表单代码的模板进行类型推断/打印:C++ 引用的模板类型推断,c++,templates,c++11,C++,Templates,C++11,我一直在使用带有表单代码的模板进行类型推断/打印: #include <iostream> template <typename T> class printType {}; template <typename T> std::ostream& operator<<(std::ostream& os, const printType<T>&) { os << "SomeType"; ret
#include <iostream>
template <typename T>
class printType {};
template <typename T>
std::ostream& operator<<(std::ostream& os, const printType<T>&)
{
os << "SomeType"; return os;
}
template <typename T>
std::ostream& operator<<(std::ostream& os, const printType<T*>&)
{
os << printType<T>() << "*"; return os;
}
template <typename T>
std::ostream& operator<<(std::ostream& os, const printType<T&>&)
{
os << printType<T>() << "&"; return os;
}
// etc... and can call on a variable through
template <typename T>
printType<T> print(T) { return printType<T>(); }
int main()
{
int a = 7;
int *p = &a;
int &r = a;
//OK: return SomeType*
std::cout << "type of p: " << print(p) << std::endl;
//Hmmmm: returns SomeType <- (no &: can I get around this?)
std::cout << "type of r: " << print(r) << std::endl;
}
#包括
模板
类printType{};
模板
std::ostream&operator没有办法解决这个问题。表达式p
,其中p
命名引用,始终具有引用所引用的类型。没有表达式具有类型T&
。因此,您无法检测表达式是否源自引用
这也不能用C++0x完成。C++的深层原理是没有引用类型的表达式。您可以编写decltype(r)
来获取r
名称的类型,而不是表达式r
的类型。但是你将无法编写print(r)
,除非print
是一个宏,当然,但我不明白你为什么要走那条可怕的路 我收回了我之前说过的话。我想我可能有办法在纯c/c++中实现这一点,尽管方式非常混乱。你会的
需要将指针传递到函数中
i、 e。
bool hello_world(std::string和my_string,const std::string*const my_string\u ptr){
bool hello_world(std::string my_string,const std::string*const my_string_ptr){
如果你现在测试
if(&my\u string==my\u string\u ptr)
如果var通过引用传递,它将计算true,如果通过值传递,它将计算false
当然,在所有函数中将变量加倍可能是不值得的
Johannes是正确的……不是纯C++。但是你可以做到这一点。窍门是作弊。使用像Perl这样的嵌入式脚本语言来搜索你的源代码。这里有一个嵌入式Perl模块:
将函数名、变量名和源位置传递给它,然后使用正则表达式查找变量并检查其类型。实际上,假设您总是手头有一个源代码,这可能是一个更好的解决方案
我将在稍后发布此基本方法的函数…必须处理一些早上的工作!:)
即使您不想分发源代码,您也可以创建某种打包函数/var数据文件,通过@runtime进行解析,并获得等效的结果
编辑1
例如,使用Perl嵌入教程中的#I32 match(SV*string,char*pattern)
函数,您可以执行以下操作:
bool is_reference(const char * source_loc, const char * function_name,
const char * variable_name) {
std::ifstream my_reader;
char my_string[256];
SV * perl_line_contents;
bool ret_val = false;
char my_pattern [400]=strcat("m/.*",function_name);
my_pattern=strcat(my_pattern, ".*[,\s\t]*");
my_pattern=strcat(my_pattern, variable_name);
my_pattern=strcat(my_pattern, "[\s\t]*[\(,].*$");
my_reader.open(source_loc.c_str());
while (!my_reader.eof()) {
my_reader.getline(my_string,256);
sv_setpv(perl_line_contents,my_string);
if(match(perl_line_contents,my_pattern)) {
ret_val= true;
}
}
return ret_val;
}
…有两种方法可以做到这一点(请参见上面的更新)。您可以将SFINAE与整数类型一起使用,或者通过这种方法从“0”转换任何内容:
template <typename T>
class is_reference
{
struct yes { char a, b; };
typedef char no;
template <typename U> static no test(T y) { }
template <typename U> static yes test(...) { }
public:
static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};
#include <iostream>
struct not_constructable_from_int {};
struct constructable_from_int { constructable_from_int(int x) { } };
int
main()
{
std::cout << is_reference<int>::value << std::endl;
std::cout << is_reference<int&>::value << std::endl;
std::cout << is_reference<not_constructable_from_int>::value << std::endl;
std::cout << is_reference<not_constructable_from_int&>::value << std::endl;
std::cout << is_reference<constructable_from_int>::value << std::endl;
std::cout << is_reference<constructable_from_int&>::value << std::endl;
}
模板
类是您的参考
{
结构yes{char a,b;};
typedef字符号;
模板静态无测试(Ty){}
模板静态是测试(…){}
公众:
静态常量布尔值=sizeof(测试(0))==sizeof(是);
};
#包括
结构不可从{u int}构造;
结构可构造的{u int{可构造的{u int(intx){};
int
main()
{
我能建议他作弊吗…见下文。