【发布时间】:2018-01-13 02:34:09
【问题描述】:
我一直在努力解决编译问题,并且能够将问题缩小到一个小的代码段。
为了做好准备,我正在尝试执行 CRTP,其中基方法调用派生类中的另一个方法。复杂之处在于,我想使用尾随返回类型来将转发类型直接传递给 Derived 类的方法。这总是无法编译除非我转发到派生类中的调用运算符。
这样编译:
#include <utility>
struct Incomplete;
template <typename Blah>
struct Base
{
template <typename... Args>
auto entry(Args&&... args)
-> decltype(std::declval<Blah&>()(std::declval<Args&&>()...));
};
void example()
{
Base<Incomplete> derived;
}
虽然这不是:(请注意唯一区别的注释)
#include <utility>
struct Incomplete;
template <typename Blah>
struct Base
{
template <typename... Args>
auto entry(Args&&... args)
-> decltype(std::declval<Blah&>().operator()(std::declval<Args&&>()...));
// I only added this ^^^^^^^^^^^
};
void example()
{
Base<Incomplete> derived;
}
我得到的错误:
<source>: In instantiation of 'struct Base<Incomplete>':
15 : <source>:15:22: required from here
10 : <source>:10:58: error: invalid use of incomplete type 'struct Incomplete'
-> decltype(std::declval<Blah&>().operator()(std::declval<Args&&>()...));
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
在 Derived 类中解析 decltype 期间似乎发生了一些特殊行为。标准中有什么可以解释这一点吗?
编辑:做了更大的简化
PS:在 Godbolt 上编译示例:https://godbolt.org/g/St2gYC
【问题讨论】:
-
你为什么不写
std::declval<Blah>()?我猜第二个块是Incomplete的 odr 使用,而第一个不是。 -
@PasserBy 无论哪种方式,都是同样的问题。我将其更改为您的建议,以免造成混乱。
-
您可能正在寻找这个吗? stackoverflow.com/questions/7943525/…
标签: c++ templates operator-overloading language-lawyer name-lookup