C++ 如何制作constexpr交换函数?

C++ 如何制作constexpr交换函数?,c++,swap,constexpr,string-view,C++,Swap,Constexpr,String View,为了便于学习,我正在创建自己的字符串视图类,并且我正在尝试将其设置为100%constexpr 为了测试它,我有一个返回散列值的成员函数。然后,我在switch语句中构造我的字符串视图,并调用同一个成员函数,如果它通过,则该成员函数已完成其用途 为了学习,我正在使用/阅读/比较我的实现与Visual Studio 2017最新更新std::string_view,但是,我注意到,尽管swap标记为constepr,但它不起作用,无论是在Visual Studio中还是在g++ 这是一段不起作用的

为了便于学习,我正在创建自己的字符串视图类,并且我正在尝试将其设置为100%constexpr

为了测试它,我有一个返回散列值的成员函数。然后,我在switch语句中构造我的字符串视图,并调用同一个成员函数,如果它通过,则该成员函数已完成其用途

为了学习,我正在使用/阅读/比较我的实现与Visual Studio 2017最新更新
std::string_view
,但是,我注意到,尽管
swap
标记为
constepr
,但它不起作用,无论是在Visual Studio中还是在g++

这是一段不起作用的代码:

constexpr Ali::String::View hello("hello");
constexpr Ali::String::View world("world");
// My implementation fails here!
hello.swap(world);
cout << hello << " " << world << endl;    

// Visual Studio implementation fails here!
// std::string_view with char const * is not constexpr because of the length
constexpr std::string_view hello("hello");
constexpr std::string_view world("world");
hello.swap(world);
cout << hello << " " << world << endl;
这是我班上的,和VisualStudio上的很相似

constexpr void swap(View & input) noexcept {
    View const data(input);
    input = *this;
    *this = data;
}
所有构造函数和赋值都标记为constexpr

VisualStudio和g++都给了我类似的错误

// Visual Studio
error C2662: 'void Ali::String::View::swap(Ali::String::View &) noexcept': cannot convert 'this' pointer from 'const Ali::String::View' to 'Ali::String::View &'

// g++
error: passing 'const Ali::String::View' as 'this' argument discards qualifiers [-fpermissive]

如果swap不能与constexpr一起使用,为什么要使用constexpr?

swap
被标记为允许在
constexpr
函数中调用,例如:

constexpr int foo()
{
    int a = 42;
    int b = 51;

    swap(a, b); // Here swap should be constexpr, else you have error similar to:
                // error: call to non-constexpr function 'void swap(T&, T&) [with T = int]'
    return b;
}

也许我误解了这个问题,但您是否正在尝试交换两个
constexpr
对象
constexpr
定义的对象无法修改,哪种交换可以。那么为什么在
std::string_视图中交换函数标记为constexpr
cppreference.com
std::basic_string_view::swap
的签名是
constepr void swap(basic_string_view&v)noexcept
。我想知道为什么它是
constexpr
。这很有趣。也许你应该把它作为一个问题发布。我应该删除这个问题并问一个新问题吗?这个问题还不错。我会把它放在一边,给某人一个机会来解释为什么试图交换
constexpr
对象是行不通的。它将来可能对其他用户有用。你甚至可以自己回答这个问题,解释是什么导致了你所经历的困惑,以及你是如何解决的。我现在用我自己的字符串视图实现对它进行了测试,它完全按照你说的那样工作。我仍然觉得它有点不直观,有点像语言的边缘。谢谢:)但在C++17及更早版本中不应标记为
constexpr
。它在即将到来的C++20标准中进行了更改。如果它是
constexpr
,那么它就是编译器特定的扩展。
constexpr int foo()
{
    int a = 42;
    int b = 51;

    swap(a, b); // Here swap should be constexpr, else you have error similar to:
                // error: call to non-constexpr function 'void swap(T&, T&) [with T = int]'
    return b;
}