![](/img/trans.png)
[英]How to specify type of a constexpr function returning a class (without resorting to auto keyword)
[英]Unable to get type of function returning constexpr auto
我正在嘗試在類中使用屬性系統。
屬性具有相應的成員指針,名稱和int(來自枚舉)以唯一標識它。
以下是定義屬性的代碼:
template<typename Class, typename T>
struct MemberProperty
{
constexpr MemberProperty(T Class::*aMember, const char* aName, int aId)
: member(aMember), name(aName), id(aId)
{}
T Class::*member;
const char* name;
int id;
};
我通過調用這個函數來創建屬性:
template <typename Class, typename T>
constexpr auto makeProperty(T Class::*member, const char* name, int id) {
return MemberProperty<Class, T>{member, name, id};
}
我的目標是為類定義屬性,如下所示:
class User
{
public:
enum PropertiesEnum
{
Property_Name
};
string m_name;
static constexpr auto Properties() {
return std::make_tuple(
makeProperty(&User::m_name, "name", User::Property_Name)
);
}
using PropertiesType = decltype(Properties());
//PropertyManager<PropertiesType> m_propertyManager;
};
我希望能夠取消注釋聲明m_propertyManager
的行。 問題是這不能編譯。 在g ++中,我得到:
錯誤:在扣除'auto'之前使用'static constexpr auto User :: Properties()'
在Visual Studio 2015中,我得到:
錯誤C3779:'User :: UserProperties':返回'auto'的函數在定義之前不能使用
我怎樣才能做到這一點? 它看起來像一個循環依賴,但我找不到如何讓它工作。 這是一個例子:
我想這是由於[class.mem] / 6 。
它指出:
在類說明符的結束時,類被認為是完全定義的對象類型([basic.types])(或完整類型)。 [...]
請注意特定情況的最后一條陳述:
[...]否則在其自己的類成員規范中被視為不完整。
別名聲明被視為成員規范的一部分,並且在規則的(我說的)例外中沒有提到:
[...]在類成員規范中,該類在函數體,默認參數,異常規范和默認成員初始化器(包括嵌套類中的這類事物)中被視為完整。 [...]
通過進一步減少你的例子,我們有:
struct S {
auto f() {}
using T = decltype(f());
};
int main() {}
錯誤或多或少相同。
在using聲明中,如上所述,該類不被視為完全定義的類型,因此不是其成員函數。
因此,不能扣除成員函數的返回類型,並且不能滿足使用聲明。
請注意,為了推斷返回類型,編譯器必須查看函數的定義,即函數的定義。
換句話說,它(概念上)不是這樣做的:
auto f();
using T = decltype(f());
int main() {}
如何評估尚未定義的函數的返回類型?
你不能和上面的代碼確實不起作用。
成員函數是constexpr
的事實在這種情況下不會改變任何東西。
正如對問題的評論中所提到的,您可以通過尾隨返回類型顯式指定返回類型以解決此問題。
在這種情況下,不再需要定義,您可以從聲明中獲取返回類型。 實際上,返回類型根本不會有任何扣除。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.