模板实例化源文件和行号,从中调用它

时间:2015-12-09 16:35:29

标签: c++ templates boost compilation template-meta-programming

在以下代码中:

   template< typename T, typename ValueType>
   bool SomeFunction(
        SomeWrapper<T> volatile& ioTarget,
        ValueType inCompare,
        ValueType inNewValue)
    {
         BOOST_STATIC_ASSERT(sizeof(SomeWrapper<T>) == sizeof(int));
    }

Boost Static Assert失败并出现编译时错误。

Getting sizeof(T) 帮助我在编译时获得了大小作为警告。

在分析编译器消息时,它没有指向实现此Templatized Call的实际源代码位置。

是否有任何其他模板化技术可用于获取有关实际源代码文件的信息以及调用此函数的行。

PS:我考虑过__FILE__,但这是一个宏在编译时没用。

2 个答案:

答案 0 :(得分:0)

您可以通过其他方式使代码失败,使编译器输出您需要的信息。这可以是例如在断言失败的情况下,通过做一些不完整的模板实例化。 举例来说,编译以下代码:

template<bool>
struct tester;

template<>
struct tester<true> { }; // only define template for 'true'

template<class T>
void func(T t)
{
   tester<sizeof(T) == sizeof(int)>();
}

int main()
{
   int i;
   func(i);   // <- this call is ok :)
   double d;
   func(d);   // <- this is line 18, the offending call :(
   return 0;
}

使用gcc进行编译时,给出以下输出:

g++-4.9 -O3 -fexpensive-optimizations -Drestrict= -std=c++11 -o main main.cpp  -pthread
main.cpp: In instantiation of ‘void func(T) [with T = double]’:
main.cpp:18:10:   required from here
main.cpp:10:4: error: invalid use of incomplete type ‘struct tester<false>’
    tester<sizeof(T) == sizeof(int)>();
    ^
main.cpp:2:8: error: declaration of ‘struct tester<false>’
 struct tester;
        ^

所以gcc现在告诉我,函数调用是从我的main.cpp文件中的第18行进行的,正确识别出有问题的行。 这应该能够提供您需要的信息。

编辑15 / 12-15: 要打印编译时警告,您需要触发软错误,这不会导致编译器错误。这可以是例如是一个溢出警告。 为了简短起见,代码看起来像这样:

///
// struct that will overflow and print integer s at compile-time
////
template<unsigned s>
struct overflow
{
   operator char() { return (s + 256); }
};

/////
// function that will print warning message at compile-time
// warning message must be made as a class/struct
////
template<class MESSAGE>
void print_warning(MESSAGE)
{
   char(overflow<sizeof(MESSAGE)>());
};

struct this_is_a_warning // warning message
{
};

template<class T>
void func()
{
   print_warning(this_is_a_warning()); // <- this will print a warning, line 27
}

int main()
{
   func<double>(); // <- line 32
   return 0;
}

使用gcc进行编译可以得到:

g++-4.9 -O3 -fexpensive-optimizations -Drestrict= -std=c++11 -o main main.cpp  -pthread main.cpp: In instantiation of ‘overflow<s>::operator char() [with unsigned int s = 1u]’: 
main.cpp:17:4:   required from ‘void print_warning(MESSAGE) [with MESSAGE = this_is_a_warning]’ 
main.cpp:27:37:   required from ‘void func() [with T = double]’
main.cpp:32:17:   required from here 
main.cpp:7:37: warning: overflow in implicit constant conversion [-Woverflow]
    operator char() { return (s + 256); }

&#39;显然&#39;显示函数调用跟踪,以main.cpp的第32行结束。

答案 1 :(得分:0)

我正在使用XCode 6.3 LLVM,但它没有提供失败的确切行号。 但在分析编译器日志时,它会在报告错误后告知此信息。

所以只是在错误解决后查看日志。 现在我能够找到这个实例。

但这仍然是一个悬而未决的问题,如果该模板成功实例化,是否有任何元编程技术可以告诉某些警告(而不是错误)该模板是从X文件和Y行号实例化的。