Search code examples
c++visual-studio-2017c++17variadic-templatesfold-expression

Variadic functions and fold expression: Fatal Error while trying to compile in Visual Studio 2017


I was reading this Q/A and some of the answers provided a possible solution for using Fold Expressions in C++17. I thought I'd try this technique within my own code.

This is what I have tried:

Some Header

#pragma once

#include <bitset>
#include <type_traits>

using Bit = std::bitset<1>;

template<typename... Bits>
typename std::enable_if<(std::is_same<Bits, Bit>::value && ...), Bit>::type
And(Bits... bits) {
    return (bits&...);
}

main.cpp

#include <iostream>
#include "Some Header"

int main()
{   
    Bit b1_0{0};
    Bit b1_1{1};
    Bit b2_0{0};
    Bit b2_1{1};

    // Intended uses:
    Bit res1 = And(b1_0, b1_1, b2_0); // res1 should = 0
    Bit res2 = And(b1_1, b2_1); // res2 should = 1

    std::cout << "res1 = " << res1.to_string() << '\n';
    std::cout << "res2 = " << res2.to_string() << '\n';

    return 0;
}

I'm using Visual Studio 2017; and this fails to compile I am getting a "fatal error C1001".

I don't know if it is coming from the fold expression or if how I am trying to apply the repeated & on each Bit that is passed into the function etc.

When I try this using Compiler Explorer: goldbot It compiles fine using either GCC or Clang but fails in Visual Studio...

How would I be able to do something similar to this that works in Visual Studio?


Solution

  • Playing with goldbot seems that your code compile starting from MSVC v19.21.

    I don't understand what wrong before; anyway, passing through a constexpr function as follows

    template <typename ... Bits>
    constexpr bool all_bits ()
    { return (std::is_same_v<Bits, Bit> && ...);  }
    
    template<typename... Bits>
    std::enable_if_t<all_bits<Bits...>(), Bit>
     And(Bits... bits) {
        return (bits & ...);
    }
    

    seems to works also with v19.20 and older versions.