是否可以在非文本类型上参数化 constexpr 类模板文本类型

Can a constexpr class template literal type be parameterized on a non-literal type?

本文关键字:文本 类型 constexpr 参数 是否      更新时间:2023-10-16

>我正在使用gcc 4.9.2的ORM设计。我有一个由2名成员组成的班级:

class Staff : public Db::TableBase<Staff> {
public:
    long int staffId_;
    std::string nickname_;
}

(TableBase 是我用来将几个静态函数和子类声明拉入类范围的类。它没有成员或方法,只有静态函数和子类声明。

我为每个成员都有一个列对象:

static constexpr auto colTest1=Db::detail::ColumnObject<Staff,long int>
    (&Staff::staffId_,"staff_id",Db::BigSerial | Db::Default,Db::Transport::TEXT);
static constexpr auto colTest2=Db::detail::ColumnObject<Staff, std::basic_string<char> >
    (&Staff::nickname_,"nick_name",Db::NotNull,Db::Transport::TEXT);

第一个语句编译,第二个语句不编译:

~/git/WebSchedule2/src/common/ORM/Staff.hpp:110:152: error: ‘const Db::detail::ColumnObject<Staff, std::basic_string<char> >{&Staff::nickname_, ((const char*)"nick_name"), 1, (Db::Transport)0, -1}’ is not a constant expression
static constexpr auto colTest2=Db::detail::ColumnObject<Staff, std::basic_string<char> >(&Staff::nickname_,"nick_name",Db::NotNull,Db::Transport::TEXT);

你可能会说,第二个语句不编译的原因是,对 std::string 的类型依赖使它成为非文字。但是,我实际上并没有在 ColumnObject 的定义中使用字符串,我只使用类型信息。ColumnObject 的定义:

template<typename Derived,typename MemberType>
class ColumnObject {
public:
    MemberType Derived::*memberPtr_;
    char const *columnName_;
    int const traits_;
    Db::Transport transport_;
    int columnNumber_;
    constexpr ColumnObject()
        : memberPtr_(nullptr), columnName_("UNITIALIZED COLUMN"), traits_(-1), 
            transport_(Db::Transport::TEXT), columnNumber_(-1) { }
    constexpr ColumnObject(MemberType Derived::*memberPtr, char const *columnName,
        int const traits, Db::Transport transport)
        : memberPtr_(memberPtr), columnName_(columnName), traits_(traits),
            transport_(transport), columnNumber_(-1) { }
}

任何想法如何解决这个问题?

(编辑:我在下面包括一个完整的例子。问题似乎是使用静态常量。

// g++ -Wall -Wextra -pedantic -std=c++14 -c foo.cpp
#include <string>
template<typename Derived,typename MemberType>
class ColumnObject;
template<typename Derived,typename MemberType>
class ColumnObject {
public:
    MemberType Derived::*memberPtr_;
    char const *columnName_;
    constexpr ColumnObject()
        : memberPtr_(nullptr), columnName_("UNITIALIZED COLUMN") { }
    constexpr ColumnObject(MemberType Derived::*memberPtr, const char *columnName)
        : memberPtr_(memberPtr), columnName_(columnName) { }
};
class Staff {
public:
    long int staffId_;
    std::string nickname_;
    Staff(){
        staffId_=0;
        nickname_="";
    }
    Staff(long int snid, std::string nname)
        : staffId_(snid), nickname_(nname)
    {
    };
    static constexpr auto colTest1=ColumnObject<Staff,long int>(&Staff::staffId_,"staff_id");
    static constexpr auto colTest2=ColumnObject<Staff, std::string >(&Staff::nickname_,"nick_name");
};
int main(int argc, char *argv[]){
    constexpr auto colTest3=ColumnObject<Staff,long int>(&Staff::staffId_,"staff_id");
    constexpr auto colTest4=ColumnObject<Staff, std::string >(&Staff::nickname_,"nick_name");
}

在这里工作正常,在 clang :) -> coliru.stacked-crooked.com/a/b9a3102e4849b0d0 – pepper_chico

这现在适用于 RedHat gcc 5.3.1-2。 – user2352497