C++ SFINAE关于模板实例化的错误?

C++ SFINAE关于模板实例化的错误?,c++,templates,c++14,template-meta-programming,sfinae,C++,Templates,C++14,Template Meta Programming,Sfinae,我的要求可能是不可能的,但我会要求只是为了确定。如前所述,具有自动返回类型的函数可能不可用,因为返回类型的推导会导致模板实例化。在实例化过程中,编译器将产生一个错误 然而,也许有人知道一些疯狂的把戏,将一段代码中的实例化错误转化为另一段代码中的替换失败,从而导致SFINAE 下面是一段导致错误的代码示例: #include <utility> struct no_call_ops { }; struct caller { // Goal is to detect whet

我的要求可能是不可能的,但我会要求只是为了确定。如前所述,具有自动返回类型的函数可能不可用,因为返回类型的推导会导致模板实例化。在实例化过程中,编译器将产生一个错误

然而,也许有人知道一些疯狂的把戏,将一段代码中的实例化错误转化为另一段代码中的替换失败,从而导致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{};
结构调用程序
{
//目标是检测特定的处理程序类型
//可以传给呼叫者吗
模板
自动运算符()(处理程序和处理程序,int v)
{
处理程序(3.14);
而(v--)
{
handler(“你好世界”);
}
//等等。。。
//我不想给handler打更多的电话
//在尾部返回类型中使用express。
}
};
结构回退{};
结构测试仪
{
//如果这次失败了那就太好了。。。
模板
自动运算符()
->decltype(调用方(处理程序,std::forward)


谢谢!

这种尾随返回类型可以接受吗

#include <utility>
#include <functional>
using namespace std;

struct no_call_ops { };

template<class T>
using int_t = int;

struct caller
{
  template <typename Handler, int_t<typename result_of<Handler>::type> = 0>
  auto operator() (Handler&& handler, int) -> typename result_of<Handler>::type
  {
    handler(3.14);    
  }
};


struct fallback { };

struct tester
{
  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{}; }  
};

using detected_t = decltype(tester{}(caller{}, no_call_ops{}, 42));
#包括
#包括
使用名称空间std;
结构no_call_ops{};
模板
使用int_t=int;
结构调用程序
{
模板
自动运算符()(Handler&&Handler,int)->typename result\u of::type
{
处理程序(3.14);
}
};
结构回退{};
结构测试仪
{
模板
自动运算符()(调用者和调用者,处理者和处理者,Args和…Args)->decltype(调用者(处理者,std::forward(Args)…)
{ }
回退运算符()(…){return fallback{};}
};
使用detected_t=decltype(tester{}(caller{},no_call_ops{},42));

这对你有用吗

#include <utility>

struct no_call_ops { };

struct caller
{
  template <typename Handler, class = decltype( std::declval<Handler>()(3.14) )>
  decltype(auto) operator() (Handler&& handler, int)
  {
    handler(3.14);    
  }
};

struct fallback { };

struct tester
{
  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{}; }  
};

using detected_t = decltype(tester{}(caller{}, no_call_ops{}, 42));
#包括
结构no_call_ops{};
结构调用程序
{
模板
decltype(自动)运算符()(处理程序和处理程序,int)
{
处理程序(3.14);
}
};
结构回退{};
结构测试仪
{
模板
自动运算符()(调用者和调用者,处理者和处理者,Args和…Args)->decltype(调用者(处理者,std::forward(Args)…)
{ }
回退运算符()(…){return fallback{};}
};
使用detected_t=decltype(tester{}(caller{},no_call_ops{},42));

您希望发生什么?no\u call\u ops没有运算符(),因此尝试调用它是一个错误。SFINAE仅对函数/类型的类型数据有效,而对包含的代码无效。您可以将SFINAE放在运算符()上为了确保处理程序是回调,但我不确定这是否是您想要的…可能我猜这就是我试图做的,是对包含的代码进行定义。最终结果是所有内容都会编译,而检测到的
回退类型。因此,我认为这可能是不可能的,因为我正在询问编译器扔掉它实例化的代码。为了进一步激发我的努力,假设处理程序被多次调用,使用不同的类型。我不想在那里创建一个尾随返回类型,因为它太复杂了,我无法表达。不确定我到底做了什么…但我确实使用了尾随返回类型。是的,这很有效(而且你甚至不需要
int\t
之类的东西。我的要求是不需要尾随返回类型,而只需要auto。我将稍微改变一下问题:为什么没有尾随返回类型?因为你的真实代码比示例更复杂?或者……另外,如果没有int\t之类的东西,它将根据句柄的返回类型而中断。)r(即,如果它不是整数类型)…我认为您可以尝试使用适当的输入类型将处理程序填充到std::函数中,以简化必须执行大量declval操作…或者传入一组类型的参数包并执行declval()。。。