2016-08-30 92 views
9

問題:是否有可能通過將參數傳遞給內部constexpr函數(可能帶有某種「完美轉發」)來評估函數內部的常量表達式? 例子:有沒有辦法將參數轉發到內部constexpr函數?

constexpr size_t foo(char const* string_literal) { 
    return /*some valid recursive black magic*/; 
} 

void bar(char const* string_literal) { 
    // works fine 
    constexpr auto a = foo("Definitely string literal."); 
    // compile error: "string_literal" is not a constant expression 
    constexpr auto b = foo(string_literal); 
} 

template<typename T> 
void baz(T&& string_literal) { 
    // doesn't compile as well with the same error 
    constexpr auto b = foo(std::forward<T>(string_literal)); 
} 

int main() { 
    // gonna do this, wont compile due to errors mentioned above 
    bar("Definitely string literal too!"); 
} 

找不到什麼明確的禁止documentation,但解決的辦法是找不到的,以及不可能性的證明。內在表達的共同性很重要。

+0

https://stackoverflow.com/questions/26582875/constexpr-function-parameters-as-template-arguments – SomeWittyUsername

回答

7

參數constexpr函數不能被假定爲constexpr函數內的constexpr函數;該功能必須工作,如果他們不是constexpr

類型參數可以。

如果您將bar("hello")替換爲bar(string_constant<'h', 'e', 'l', 'l', 'o'>{})template<char...>struct string_constant{};,則字符的值現在編碼爲該類型,並且可在路徑下使用。還有其他方法可以將字符變爲一種類型。

2

不幸的是,這是無法實現的。 constexpr功能的參數也不是自動constexpr。該功能畢竟可以從非constexpr上下文中調用。您的編譯器可能能夠將您的情況優化爲編譯時評估,但這無法得到保證。

有一個常規的解決方法,使用模板參數強制一種參數的一種constexpr。你可以在this question找到一個很好的例子。在這之後,人們可能會傾向於這樣做:

template<const char * string_literal> void baz() { 
    constexpr auto b = foo(string_literal); 
} 

int main() { 
    baz<"Definitely string literal too!">(); 
} 

然而,這種帶有非類型模板參數的限制,其中一個說,一個字符串字面量不能爲非類型模板參數。如果Yakk建議您可以使用variadic char模板,如果這可以應用於您的案例。

將來可能會增加對constexpr函數參數的支持。有關於ISO C++ Google Groups here的討論。

你也可以將baz轉換成某種參數化宏,如果你真的需要完成這項工作。

相關問題