请参阅 SFINAE 某个功能的原因

See SFINAE reason for a certain function

我正在使用 CLang。有没有办法让某个函数或整个 .cppSFINAE 视为错误?如果某个功能有选项--sfinae-as-error,或者#pragma sfinae_disable/#pragma sfinae_enable

似乎由于 SFINAE,我的功能专业化已经消失(变得无法使用),我不知道如何找到它失败的原因(SFINAE 来自哪里),基本上我有无意的 SFINAE 案例,我想找出导致它的行。

为了解释这个,我有一个小方法:

template <typename To>
auto casttc() const {
    if constexpr(std::is_same_v<To, T>)
        return *this;
    Vec<RTBits, Bits, To> c;
    auto constexpr castt_ = castt_reg_helper<RTGet<To>, RT>::f;
    LOOPM({ GI; c.template reg<I>() = castt_(this->template reg<I>()); });
    return c;
}

从另一种方法我称它为 this->template casttc<u64>() 并且它给出了编译错误:

drafts/intrin_simd3.hpp:199:10: note: candidate template ignored: substitution failure [with To = unsigned long long]
    auto casttc() const {

上述错误消息中的第 199 行指向 auto casttc() const {

有几个错误日志屏幕,这些行是此日志的最后几行:

In file included from drafts/cordic.cpp:12:
In file included from drafts/intrin_simd3.hpp:157:
drafts/intrin_simd2.hpp:140:61: error: no matching member function for call to 'casttc'
        *this = this->template casttc<T0>().and_(b.template casttc<T0>()).template casttc<T>();
                                                 ~~~~~~~~~~~^~~~~~~~~~
drafts/intrin_simd3.hpp:199:10: note: candidate template ignored: substitution failure [with To = unsigned long long]
    auto casttc() const {

所以基本上它说由于某种原因 <u64> 不能使用这个函数的特化。而且我事先不知道是什么导致了这个问题。

一段时间后,我设法找出了问题所在,即 castt_reg_helper<RTGet<To>, RT> 没有对给定模板参数进行专门化处理。在我添加了必要的专业化之后,一切都开始编译了。

所以我担心 CLang 没有给我准确的错误原因,它只是说 <u64> 专业化在没有额外原因的情况下无法使用。据我了解,由于 SFINAE,此专业已被删除(或变得无法使用)。因此,对于类似的情况,我希望能够在没有编译器静默使用 SFINAE 的情况下看到失败的确切原因。

在我的案例中,功能不是很大,我能够手动找到错误。但是如果一个函数的主体很大(我以前有过这种情况),找到 SFINAE 的原因可能会有问题并且需要很多时间。

基本上我的构建系统只是输出最后一个错误屏幕,它将错误截断到控制台上显示的最后一个屏幕。因为在屏幕的开头它显示了截断发生的小消息,但我没有注意到。当我恢复整个日志时,出现以下几行:

In file included from drafts/cordic.cpp:12:
drafts/intrin_simd3.hpp:203:33: error: implicit instantiation of undefined template 'asimd::Vec<256, 512, double>::castt_reg_helper<__attribute__((__vector_size__(4 * sizeof(long long)))) long long, __attribute__((__vector_size__(4 * sizeof(double)))) double>'
        auto constexpr castt_ = castt_reg_helper<RTGet<To>, RT>::f;
                                ^

这解决了我的问题。显然,这似乎不是 SFINAE 的原因,而且 CLang 实际上显示了详细的原因,但远在错误日志中。

所以我的问题是一个错误,不是因为 CLang 不好,而是因为我没有注意到我的构建系统被截断了错误。

我们有一个专门为我们的组织和需求编写的特殊构建系统。它不是任何众所周知的开源构建系统。