Microsoft Visual C++ 中的 SFINAE constexpr 错误

Posted

技术标签:

【中文标题】Microsoft Visual C++ 中的 SFINAE constexpr 错误【英文标题】:SFINAE constexpr error in Microsoft Visual C++ 【发布时间】:2021-10-27 05:57:50 【问题描述】:

使用constexpr 的简单 SFINAE 代码无法编译。相同的代码在 g++ 中编译。

仅当使用constexpr 时才会出现此问题。在使用std::is_integral_v<T> 时,它会编译。

// test code
#include<iostream>

template<typename T>
constexpr inline bool is_integral() 
    return std::is_integral_v<T>;


template<typename T>
constexpr inline bool is_floating_point() 
    return std::is_floating_point_v<T>;


struct tester 
template<typename T>
std::enable_if_t<is_integral<T>(), void> operator()(int* p)
    //integral version
    std::cout<<"integral\n";

template<typename T>
std::enable_if_t<is_floating_point<T>(), void> operator()(int* p)
    //floating point version
    std::cout<<"floating\n";



  template <typename T, typename... Args>
  std::enable_if_t<!is_integral<T>() && !is_floating_point<T>(), void> operator()(Args&&...)
  
    std::cerr<<"not supported.\n";
  
;


enum class type  INT, FLOAT, STRING;

void type_dispatcher(type tp) 
    tester t;
    switch(tp) 
        case type::INT:
            t.operator()<int>(nullptr);
            break;
        case type::FLOAT:
            t.operator()<float>(nullptr);
            break;
        default:
            std::cout<<"Unsupported\n";
    


int main() 
    type t1type::INT, t2type::FLOAT, t3type::STRING;
    type_dispatcher(t1);
    type_dispatcher(t2);
    type_dispatcher(t3);
    return 0;

错误: cl.exe /std:c++17 ..\sfinae_test.cpp

Microsoft (R) C/C++ Optimizing Compiler Version 19.29.30136 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

sfinae_test.cpp
..\sfinae_test.cpp(21): error C2535: 'enable_if<0,void>::type tester::operator ()(int *)': member function already defined or declared
..\sfinae_test.cpp(16): note: see declaration of 'tester::operator ()'
..\sfinae_test.cpp(44): error C2672: 'tester::operator ()': no matching overloaded function found
..\sfinae_test.cpp(44): error C2893: Failed to specialize function template 'enable_if<0,void>::type tester::operator ()(int *)'
..\sfinae_test.cpp(16): note: see declaration of 'tester::operator ()'
..\sfinae_test.cpp(44): note: With the following template arguments:
..\sfinae_test.cpp(44): note: 'T=float'

将所有代码折叠成if constexpr 可以。 相关问题:https://developercommunity.visualstudio.com/t/constexpr-function-in-sfinae/1048586

这个问题有什么解决方案/破解方法吗?

【问题讨论】:

编译成功godbolt.org/z/5547Ga7Ed。前两个模板没有使用。 @S.M.:OP 展示了工作示例( :-( )并解释了错误的示例(使用未使用的方法)Demo。 我的错。更新了代码。使用前 2 个模板时,编译失败。 “这个问题有什么解决方案/破解方法吗?” 您已经找到了错误报告和解决方法(直接使用std::is_integral_v&lt;T&gt;if constexpr),不确定你还想要什么。 我正在使用constexpr函数,因为里面的条件很复杂。因此,我正在寻找使用constexpr 或以某种方式允许使用复杂条件而不会过于冗长的解决方案/hack。 【参考方案1】:

您可以使用enable_if 作为模板参数,如this。

【讨论】:

以上是关于Microsoft Visual C++ 中的 SFINAE constexpr 错误的主要内容,如果未能解决你的问题,请参考以下文章

Microsoft visual c++弹窗?

Microsoft Visual C++ 中的 SFINAE constexpr 错误

在 Microsoft Visual Studio 中的 x86 C++ 应用程序中集成犰狳

C++笔记一:Microsoft Visual Studio 2010软件的安装与建立第一个cpp文件

Microsoft Visual C++ 6.0中的绘图库文件是啥

Microsoft Visual C++ Runtime Libuary