使用变体和访客习语来处理数学表达式的抽象语法树我遇到了警告undefined reference to 'function_name'
前面的链接器错误inline function 'function_name' is not defined [-Wundefined-inline]
,其中function_name
是所有可能的专业名称(即B
和C
),标记为// 1
下方的函数(标题):
#pragma once
#include <utility>
#include <iostream>
#include <boost/variant.hpp>
struct A {};
struct B {};
struct C {};
using V = boost::variant< A, B, C >;
struct visitor
{
using result_type = void;
result_type
operator () (V v) const
{
#if 1
return boost::apply_visitor([this] (auto && x) -> result_type { return apply(std::forward< decltype(x) >(x)); }, v);
}
#else
return boost::apply_visitor(*this, v);
}
template< typename T >
result_type
operator () (T && x) const
{
return apply(std::forward< T >(x));
}
#endif
private :
result_type
apply(A) const
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
template< typename T >
result_type
apply(T &&) const // 1
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
public : // !
};
(main.cpp中):
#include "implementation.hpp"
#include <cstdlib>
int
main()
{
visitor{}(V{B{}});
return EXIT_SUCCESS;
}
以下是实例:main.cpp和header个文件。如果contents of header file移至main.cpp
,则警告已更改为function 'function_name' has internal linkage but is not defined [-Wundefined-internal]
。但我确信错误的来源完全一样。
如果我将#if 0
更改为#if 1
,那么所有编译都可以。另一个注意事项是:当我将result_type operator () (V v) const
移动到第二个public
部分(标记为// !
)时,所有编译都会很好。
似乎lambda通过严格定义lambda定义的函数模板的实例化做了一些微妙的事情。
如何解释传递给visitor &
的{{1}}的lambda版本和版本的上述行为和行为差异?
现实生活中的例子是here。