【发布时间】:2016-07-23 12:09:47
【问题描述】:
我要问的可能是不可能的,但我会问只是为了确定。正如之前在这个问题中提出和回答的:SFINAE and decltype(auto),具有自动返回类型的函数可能不是 SFINAE,因为返回类型的推导会导致模板实例化。在实例化期间,编译器会产生错误。
但是,也许有人知道一些疯狂的技巧,可以将一段代码中的实例化错误转化为另一段代码中的替换失败,从而引发 SFINAE?
以一段代码为例,它会导致错误:
#include <utility>
struct no_call_ops { };
struct caller
{
// Goal is to detect whether a particular Handler type
// will be ok to pass into caller
template <typename Handler>
auto operator() (Handler&& handler, int v)
{
handler(3.14);
while (v--)
{
handler("hello world");
}
// etc...
// more calls to handler that I don't want to
// express in the trailing return type.
}
};
struct fallback { };
struct tester
{
// Would be nice if this fails substitution...
template <typename Caller, typename Handler, typename... Args>
auto operator() (Caller&& caller, Handler&& handler, Args&&... args)
-> decltype(caller(handler, std::forward<Args>(args)...))
{ }
fallback operator() (...) { return fallback{}; }
};
// want detected_t to be "fallback"
using detected_t = decltype(tester{}(caller{}, no_call_ops{}, 42));
谢谢!
【问题讨论】:
-
您希望发生什么? no_call_ops 没有 operator(),所以试图调用它是一个错误。 SFINAE 仅适用于函数/类型的类型数据,而不适用于包含的代码。您可以将 sfinae 放在您的 operator() 上,以确保 Handler 是回调,但我不确定这是否是您想要的。 ...也许
-
我想这就是我想要做的,是包含代码的 SFINAE。最终结果将是一切都编译,
detected_t是fallback类型。因此,为什么我认为这可能是不可能的,因为我要求编译器丢弃它实例化的代码。为了进一步激发我想要做的事情,想象一下处理程序被多次调用,具有不同的类型。我不想在那里创建一个尾随返回类型,因为它对我来说太复杂了。 -
不确定我到底做了什么...godbolt.org/g/v4Mn5i 但我确实使用了尾随返回类型。
-
是的,这行得通(你甚至不需要
int_t的东西。我的要求是没有尾随返回类型,只有自动。我会稍微改变一下问题:P -
为什么没有尾随返回类型?因为您的真实代码比示例更复杂?或...此外,如果没有 int_t 的东西,它会根据 Handler 的返回类型(即,如果它不是整数类型)而中断。我认为
标签: c++ templates c++14 template-meta-programming sfinae