1

So in the latest Visual Studio 2015 the following code seems to no longer work:

template<class F>
struct wrapper
{
    constexpr wrapper()
    {}
};

template<typename T> 
constexpr typename std::remove_reference<T>::type *addr(T&& t) 
{ 
    return &t; 
}

template<class F>
constexpr wrapper<F> wrap(F*)
{
    return wrapper<F>();
}


const constexpr auto add_one = wrap(true ? nullptr : addr([](int x)
{
    return x + 1;
}));

Visual Studio reports back illegal initialization of 'constexpr' entity with a non-constant expression. This used to work in the release candidate, but the latest build seems to no longer work(I am using version 14.0.23107.0). This should work(it does work in both clang and gcc).

Unfortunately, Microsoft doesn't let me report bugs. So does anyone know of a workaround?

2
  • The problem is not exactly what you say it is. Change true ? nullptr : addr(...) to true ? (void *) 0 : addr(...) and it gets accepted, even if it uses a lambda. (I understand that that prevents add_one from having the type you want it to have, and I am not suggesting this as a replacement.) Commented Jul 29, 2015 at 21:37
  • If you want to report bugs, try connect.microsoft.com/VisualStudio (oh well, it says "You are not authorized to submit the feedback for this connection." to me) Commented Jul 30, 2015 at 12:59

1 Answer 1

2

Ok, so it seems that visual studio has a problem with conversion of pointers with constexpr as @hvd has pointed out. A workaround, I found, I can do this instead:

template<class F>
struct wrapper
{
    constexpr wrapper()
    {}
};

struct wrapper_deduce
{
    constexpr wrapper_deduce()
    {}
    template<class T>
    constexpr operator wrapper<T>() const
    {
        return wrapper<T>();
    }
};


template<class F>
constexpr wrapper<F> wrap_direct(const F&)
{
    return wrapper<F>();
}


const constexpr auto add_one = true ? wrapper_deduce() : wrap_direct([](int x)
{
    return x + 1;
});
Sign up to request clarification or add additional context in comments.

4 Comments

So, you want a constexpr variable with the type wrapper<?>, where ? is the type of a lambda that adds 1 to its int argument, but with no way (within defined behavior) to either create or run a lambda of that type?
@Yakk This is the Paul that wrote Static Lambdas: Initializing lambdas at compile time, using return reinterpret_cast<const F&>(*this)(std::forward<Ts>(xs)...);. It is not guaranteed to work, that's for sure, but it does have a static_assert that would hopefully detect any problematic implementations. On many implementations, the behaviour would be defined: for types with trivial initialisation (which is admittedly not exactly what gets checked), it's valid to call instance members without actually constructing an instance of that type.
@hvd In what way is that better than a function called add_one?
@Yakk Lambdas allow specifying parameters as auto, functions don't yet. With the int though, I think I agree that there's no benefit.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.