2016-06-23 12 views
19

Zakładając mam jakiś szablon funkcja F1:Jak wykryć, czy func. to jest constexpr? i zaznacz inne funkcje. constexpr w zależności od tego?

template<typename f2> 
int f1(int i, int j) noexcept { 
    return i + j + f2(i, j); 
} 

Czy istnieje sposób, aby ustalić, czy f2(i, j) może być constexpr. (bez względu na to, czy jest to func, czy funktor) i dlatego też oznaczacie f1<f2> jako constexpr?

mam na myśli używając SFINAE tutaj trochę jak, ale nie znaleźliśmy sposobu wykrywania constexpr użyciu type traits

+2

Jestem również zainteresowany tym. Czasami chcesz przeciążyć algorytm w zależności od 'constexpr', ponieważ jedna implementacja algorytmu jest' constexpr'able, ale inna jest szybsza. – KABoissonneault

+2

Również notatka boczna, ale: 'throw()' jest przestarzałe, użyj 'noexcept', jeśli możesz (lub usunąć go z twojego przykładu, to naprawdę nie jest istotne dla twojego problemu) – KABoissonneault

+0

@KABoissonneault, dziękuję, używając 'throw() "to tylko nawyk. –

Odpowiedz

11

Można oznaczyć f1 jak constexpr.

template<typename f2> 
constexpr int f1(int i, int j) noexcept { 
    return i + j + f2(i, j); 
} 

Funkcja f1 szablon byłby constexpr IIF f2 jest.

jeśli nie jest f2, błąd pojawi się tylko wtedy, gdy użyjesz f1 w wyrażeniu o stałej długości kompilacji.

Demo

+0

Dobra odpowiedź, ale myślę, że te nawiasy po 'noexcept' są nieprawidłowe – KABoissonneault

+0

@KABoissonneault: poprawiono literówkę. – Jarod42

+1

@AmaboCarab nie użyłeś funkcji * szablon * w twoim przykładzie. Myślę, że to jest kluczowe, aby to zadziałało. – user2079303

6

Najprostszym sposobem sprawdzenia, czy dana funkcja (np foo) jest constexpr jest przypisanie jej wartości zwracanej do constexpr jak poniżej:

constexpr auto i = foo(); 

jeśli zwrócona wartość nie jest constexpr kompilacja zakończy się niepowodzeniem.

Jeśli chcesz test SFINAE aby sprawdzić, czy funkcji (np foo) jest constexpr można użyć cechę std::integral_constant typ:

std::integral_constant<int, foo()>::value 

Live Demo

+4

To nie wydaje się być przyjaznym dla SFINAE – KABoissonneault

+0

@KABoissonneault Hope, teraz jesteś objęty. – 101010

+0

Czy podczas edycji można wyświetlić przykład użycia tej opcji, np. W celu przeciążenia funkcji? Ponieważ o ile mi wiadomo, jeśli wyślesz do szablonu szablon o wartości innej niż'constexpr', to po prostu nie uda się skompilować, a nie "SFINAE". – KABoissonneault

0

Więc w końcu, wykorzystując Jarod42 wskazówkę, i'l pisać i przetestowany this example:

#include <string> 
std::string S = "123567876"; 

constexpr size_t p() noexcept { 
    return 10U; 
} 

template<const size_t = size_t()> 
constexpr size_t f(size_t i, size_t j) noexcept { 
    return std::move(i + j + S.size() + p()); 
} 

#include <iostream> 
int main() { 
    // static constexpr const auto v = f<>(1U, 2U); // error! 
    std::cout << f(1U, 2U) << "\n"; 
    return 0; 
} 

teraz pracują prawidłowo, testowałem go za pomocą GCC kompilator online, zarówno z C + +11 i C + 14.


Można dowód będzie naprawdę constexpr jeśli to możliwe poprzez usunięcie '+ S.size()':

... 
    return std::move(i + j + p()); 
... 

i odkomentowanie wartość constexpr:

... 
    static constexpr const auto v = f(1U, 2U); 
    std::cout << v << "\n"; 
... 

zobaczyć here.


P. S. Dziękuję wam!

+0

Dlaczego dzwonisz 'std: : poruszać się po podstawowych danych? 'size_t' jest już banalnie konstruktywne, nic nie dostajesz. Nie widzę też, co faktycznie robi twój szablon – KABoissonneault

+0

@KABoissonneault i nazywam go po prostu przetestowaniem, czy spełni to żądanie. Potrzebuję go, ponieważ używam go w znacznie bardziej skomplikowanym przykładzie, nazwałem go [Wykonaj funkcję członka, jeśli jest to obecny idiom] (http://www.codeproject.com/Tips/1029697/Execute-Member-Function-If -It-Is-Present), lepiej zobaczyć [najnowszą wersję] (https://github.com/RussianEmpire/GenericCPPLib/blob/master/SRC/FuncUtils.h) w repozytorium. Teraz uaktualniam go, aby był warunkowo użyty 'constexpr'. –

+0

["Jeśli żadna specjalizacja szablonu nie spełni wymagań dla funkcji constexpr lub konstruktora constexpr, jeśli zostanie uznana za funkcję inną niż szablon lub konstruktor, szablon jest źle sformułowany, nie wymaga diagnostyki."] (Http: // eel .is/C++ draft/dcl.constexpr # 6) –

Powiązane problemy