Overload a method in a way that generates a compiler error when called with a temporary

假如想象 提交于 2019-12-10 16:09:56

问题


Perhaps this piece of code will illustrate my intent best:

#include <array>

template <size_t N>
void f(std::array<char, N> arr)
{
}

template <size_t N>
void f(std::array<char, N>&& arr)
{
    static_assert(false, "This function may not be called with a temporary.");
}

f() should compile for lvalues but not for rvalues. This code works with MSVC, but GCC trips on the static_assert even though this overload is never called.

So my question is two-fold: how to express my intent properly with modern C++, and why does the compiler evaluate static_assert in a "dead" template overload that's never instantiated?

Try it online: https://godbolt.org/z/yJJn7_


回答1:


One option is to remove the static_assert and instead mark the function as deleted. Then if you call it with an rvalue you will get an error saying you are trying to use a deleted function

template <size_t N>
void f(const std::array<char, N>& arr)
{

}

template <size_t N>
void f(const std::array<char, N>&& arr) = delete; // used const here just in case we get a const prvalue

int main()
{
    std::array<char, 3> foo{};
    f(foo);
    //f(std::array<char, 3>{}); // error
    return 0;
}



回答2:


Simple enough.

template <size_t N>
void f(const std::array<char, N>&& arr) = delete;



回答3:


It's possible using only a single function that takes a reference to a non-const object:

template<size_t N> void f(std::array<char, N>& arr);

No more overloads needed.

This rule is enforced by the language specification. However the Visual C++ compiler have an extension that allows rvalues to be passed to such a function.




回答4:


An addition to other answers, I'd like to note that there is an example in the Standard library that corresponds exactly to what OP wants - std::addressof:

template<class T>
constexpr T* addressof(T&) noexcept;

template<class T>
const T* addressof(const T&&) = delete;


来源:https://stackoverflow.com/questions/52995657/overload-a-method-in-a-way-that-generates-a-compiler-error-when-called-with-a-te

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!