2016-09-22 27 views
0

使用关键字auto编程时,知道编译器在编译时使用的类型有时会很方便。如果编译中止了我需要知道类型的地方,则无关紧要。简单的例子:在编译时获取表达式的类型

std::vector<int> s{1, 2, 3}; 

for (auto elem : s) { 
    elem = 5; 
} 

for (auto elem : s) { 
    std::cout << elem << std::endl; 
} 

将打印

1 
2 
3 

因为ELEM的类型int,不int&的。尝试编译代码并获得elem类型以尽早发现此类错误会很好。

+0

不知道你在问什么。你要写的任何代码确保'elem'是一个引用,看起来比写'auto && elem'开始的时间要长。 – Barry

+3

您可以使用['std :: is_reference'](http://en.cppreference.com/w/cpp/types/is_reference)和['static_assert'](http://en.cppreference.com/w/CPP /语言/ static_assert)。但是它补充说,对于每一个循环来说,更多的工作不仅仅是确保使用正确的类型来开始。不,没有办法让编译器为你做检查,因为这个任务不是无效的。 –

+2

您的示例看起来是编译器警告的好理由。例如,我的编译器说'警告:变量'elem'设置但未使用'。 – Sergey

回答

5

经典方法是声明模板结构,而不定义:

template <typename> struct Debug; 

,然后使用它:

template struct Debug<std::string>; 

for (auto elem : s) { 
    Debug<decltype(elem)>{}; 

    elem = 5; 
} 

消息错误看起来像

error: explicit instantiation of 'struct Debug<std::__cxx11::basic_string<char> >' before definition of template 
template struct Debug<std::string>; 
       ^~~~~~~~~~~~~~~~~~ 

error: invalid use of incomplete type 'struct Debug<int>' 
     Debug<decltype(e)>{}; 

Demo

顺便说一句,现在有些IDE显示类型时鼠标在auto或可变。

+0

太棒了!我更喜欢这一点 - 不幸的是我无法找到这种类型的解决方案,我的谷歌foo :( – hochl

1

其实我只是找到了答案,以我自己的问题:

template<typename T> 
void show_type_abort_helper() 
{ 
    return __PRETTY_FUNCTION__; 
} 

#define show_type_abort(x) show_type_abort_helper< decltype(x) >() 

用法:

std::vector<int> s{1, 2, 3}; 

for (auto elem : s) { 
    show_type_abort(elem); 
    elem = 5; 
} 

产生一个与g++以下错误消息(6.1.1版本):

$ g++ test.cpp 
test.cpp: In instantiation of ‘void show_type_abort_helper() [with T = int]’: 
                     ^^^ 
test.cpp:17:9: required from here 
test.cpp:7:12: error: return-statement with a value, in function returning 'void' [-fpermissive] 
    return __PRETTY_FUNCTION__; 

检查输出T = int以查看编译器使用int作为类型。这似乎与铛工作,以及:

$ clang++-3.8 -std=c++11 test.cpp 
test.cpp:7:5: error: void function 'show_type_abort_helper' should not return a value [-Wreturn-type] 
    return __PRETTY_FUNCTION__; 
    ^ ~~~~~~~~~~~~~~~~~~~ 
test.cpp:17:9: note: in instantiation of function template specialization 'show_type_abort_helper<int>' requested here 
                            ^^^ 
     show_type_abort(elem); 

更改为for (const auto& elem : s)

with T = const int& 
     ^^^^^^^^^^ 

show_type_abort_helper<const int &> 
         ^^^^^^^^^^^ 

这样看来我可以找出在编译时的类型和中止。这对于一个非常复杂的类型来说非常方便,它由几个typedef和模板参数组成,我只是无法看到发生了什么。

相关问题