【问题标题】:Constexpr function as template parameter for SFINAEconstexpr 函数作为 SFINAE 的模板参数
【发布时间】:2019-07-12 22:56:35
【问题描述】:

谁能澄清为什么以下方法不起作用:

#include <type_traits>
#include <iostream>

template<typename T, typename U>
constexpr bool is_same_fn()
{
    return std::is_same_v<T, U>;
}

template<typename T, std::enable_if_t<is_same_fn<T, int>(), bool> = true>
void fn2() { std::cout << "True mg\n"; }

template<typename T, std::enable_if_t<!is_same_fn<T, int>(), bool> = true>
void fn2() { std::cout << "False mg\n"; }

int main() {
    fn2<int>();
    fn2<char>();
    return 0;
}

请注意,如果我不使用函数,而是直接使用std::is_same 作为模板参数,则编译相同的东西。

我得到的错误是:

error C2995:  'void fn2(void)': function template has already been defined
message :  see declaration of 'fn2'
error C3861:  'fn2': identifier not found

语言标准正确设置为:ISO C++17 Standard (/std:c++17)。 这发生在 MSVC 2019 版本 16.1.6

【问题讨论】:

  • 什么编译器、版本和命令行?这对我有用,请参阅:wandbox.org/permlink/7cMUXjWcIslirGqe(需要 C++17)
  • @PaulSanders 我认为它不应该工作。我用的是msvc,我会链接一个godbolt链接。
  • MSVC v19 编译得很好:godbolt.org/z/pXveE-
  • 这在 MSVC 2017 15.6.7 中对我来说很好用。您是否在项目的属性页中指定了 C++17(C/C++ -> 语言 -> C++ 语言标准)? MS 正在努力合规,希望没有倒退。
  • @PaulSanders 刚刚用我的 VS2017 版本进行了测试 - 工作得很好。我想他们确实已经倒退了。我会报告的,这是一周内第 4 个编译器错误 ;(

标签: c++ templates c++17 constexpr enable-if


【解决方案1】:

他们似乎在我报告后修复了它:

16.2 预览版 3 中已发布此问题的修复程序!

【讨论】:

    【解决方案2】:

    这两个函数具有相同的签名,唯一的区别是默认模板参数。要重载函数,重载必须采用不同的参数。

    您可以创建一个函数(不是 SFINAEd)并在正文中使用 if constexpr,而不是创建两个单独的函数。

    【讨论】:

    • 这里提供的代码只是说明编译器错误的最小示例。在实践中,我将它用于完全不同的目的,if constexpr 不会削减它(我需要能够通过 SFINAE 隐藏一个函数)。我在实践中遇到的问题,如果没有 constexpr 函数作为模板参数也不是不可克服的,只是没有这些会更难看。
    • 这不是编译器错误。不能有两个具有相同名称的函数采用相同的参数。
    • 这是一个编译器错误。它在 VS2017、gcc、godbolt 等中运行良好。enable_if_t 中的条件在满足/不满足条件时隐藏了其中一个功能。我可能也使用过std::is_same_v&lt;T,int&gt;,它在这个例子中也可以工作。
    猜你喜欢
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 2016-07-15
    • 2011-09-15
    • 2017-08-21
    • 1970-01-01
    • 1970-01-01
    • 2012-02-21
    相关资源
    最近更新 更多