C++ VS2015 constexpr 编译错误,constexpr 构造函数调用 constexpr 成员函数

标签 c++ string c++11 hash visual-studio-2015

我最近下载了 VS2015 并开始修补新的 C++11 功能。我的游戏引擎中缺少的功能之一是 HashedString 类。由于 C++11 引入了 constexpr,我认为 HashedString 类将是一个很好的起点。

但是,我遇到了编译错误的障碍。每当我尝试从 constexpr 构造函数的成员初始值设定项列表调用 constexpr 成员函数时,编译器都会提示成员函数调用不会产生常量表达式。我什至尝试简化 HashString 和 HashStringDJB2Recursive 调用以仅返回 0,但是,相同的编译错误仍然存​​在。如果我删除对 HashString 的调用,一切都会编译得很好。

据我研究,下面提供的成员函数不违反 C++11 constexpr 规则。我可能错过或误解了有关 C++ constexpr 规则的某些内容。任何关于为什么不能编译的澄清将不胜感激!

namespace CBConstants
{
   constexpr unsigned int HASHED_STRING_HASH_CONSTANT = 5381;
}


class HashedString
{
public:
    ~HashedString();

    explicit constexpr HashedString( const char* stringToHash ) noexcept
        : mStringHash( HashString( stringToHash ) ),
            mStringData( stringToHash )
    {

    }

    private:
    // DJB2 Hash documentation http://www.cse.yorku.ca/~oz/hash.html
    constexpr unsigned int HashedString::HashString( const char* stringToHash ) const noexcept
    {
        return ( ( !stringToHash ) ? 0 : HashStringDJB2Recursive( CBConstants::HASHED_STRING_HASH_CONSTANT, stringToHash ) );
    }


     constexpr unsigned int HashedString::HashStringDJB2Recursive( const unsigned int hashConstant, const char* stringToHash ) const noexcept
     {
        return ( !(*stringToHash) ? hashConstant : HashStringDJB2Recursive(((hashConstant << 5) + hashConstant) + (*stringToHash), stringToHash + 1 ) );
     }

    unsigned int        mStringHash;
    const char*         mStringData;

};

编译错误:

Error C2134 'HashedString::HashString': call does not result in a constant expression hashedstring.h 17 note: failure was caused by call of undefined function or one not declared 'constexpr'.

最佳答案

你的类(class)不是 literal因为你有一个不平凡的析构函数。

根据C++标准

12.4/5 A destructor is trivial if it is not user-provided and if:

— the destructor is not virtual,

— all of the direct base classes of its class have trivial destructors, and

— for all of the non-static data members of its class that are of class type (or array thereof), each such class has a trivial destructor.

Otherwise, the destructor is non-trivial.

在您的情况下,您声明了析构函数,因此析构函数并不简单。如果你这样做

~HashedString() = default;

或者甚至不声明它,代码应该可以编译。

Live example on Coliru

编辑

VC++ 似乎关心函数定义的顺序。将它们移至构造函数上方将使代码可编译(尽管 C++ 标准不强制这样做)。

Live example on rextester VC++

关于C++ VS2015 constexpr 编译错误,constexpr 构造函数调用 constexpr 成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33907196/

相关文章:

c++ - 关于在 CentOS-6.5 上安装 gcc-6.* 的问题

swift - Swift 中的字符串比较是如何发生的

c++ - 防止在模板中使用某些类型

c++ - 从 qml 访问 QList<T>

c++ - Qt - 删除快捷方式 - 不明确的快捷方式重载

javascript - 字符串到 JavaScript 数组,元素作为数组

java - 在Java中的字符串中的特定位置添加特定字符

c++ - 在 vector/矩阵中组合变量

c++ - Ubuntu 16.04 LTS 和 Oracle Instant Client - C++ 链接错误

c++ - c++中使用c头文件时是否需要在struct实例前放置 "struct"?