컴파일 타임에숫자 ...의 합을 계산하려고하지만 루프없이parameter pack를 반복하는 방법을 모르겠습니다.
#include <string>
template<int ...Numbers>
constexpr auto sum()
{
//need to return sum of Numbers...
//for(auto && i : {Numbers...})
return 0;
}
template<int N>
void test()
{
std::cout << "Sum of elements: " << N << " " << std::endl;
}
int main()
{
test<sum<1,5,7,6>()>();
}
- 답변 # 1
- 답변 # 2
이 솔루션은사용 가능되었지만
어쨌든std::accumulate
이후로는 사용할 수 없었던 솔루션입니다. 알고리즘이constexpr
가 아닙니다 . 왜 그런지 궁금합니다. 어쩌면constexpr
가 될 것입니다. C ++ 23으로?std::accumulate
라고 가정 해 봅시다.constexpr
였다 ‘즉, 귀하는 다음을 직접 구현할 필요가 없습니다.namespace std { // Again, just to be clear - this isn't actually in std right now template<class InputIt, class T> constexpr T accumulate(InputIt first, InputIt last, T init) { for (; first != last; ++first) { init = std::move(init) + *first; } return init; } } // namespace std
이제 작성해야합니다 :
template<int ...Numbers> constexpr auto sum() { #if __cplusplus >= 201703L auto numbers = std::array{Numbers...}; #else // assuming __cplusplus >= 201402L auto numbers = std::experimental::make_array(Numbers...); #endif return std::accumulate(numbers.begin(), numbers.end(), 0); }
... 이것은 C ++ 14 이상에서 작동합니다.
이제
std::accumulate
의 constexpr + ranges 버전이 있다면 , 당신은 다음과 같이 쓸 것입니다 :template<int ...Numbers> constexpr auto sum() { return std::accumulate(std::array{Numbers...}, 0); }
PS-
init
라면 더 좋았을 것입니다 매개 변수가 기본적으로T{}
로 초기화되었습니다. . - 답변 # 3
c ++ 11 또는 c ++ 14에서는 hack†으로 접기 표현을 얻을 수 있습니다.
#include <type_traits> // std::common_type template <typename ... Args> constexpr auto sum(Args&&... args) -> typename std::common_type<Args...>::type { using unused = int[]; using ReturnType = typename std::common_type<Args...>::type; ReturnType result{}; (void)unused { 0, (result += args, 0)...}; return result; }
이를 호출 할 수 있습니다 :
test<sum(1,5,7,6)>();
Variadic 템플릿 함수 (IMHO)를 만드는 자연스러운 방법과 비슷합니다. (온라인에서 C ++ 14 솔루션 라이브 참조)
<시간>의 의견에서@einpoklum제안에 따라 C +에 대한 람다의 도움으로 동일한 기법 (런타임)을 보여주고 싶습니다 +11 및 C ++ 14 컴파일러 :
#include <type_traits> // std::common_type template <int... Args> constexpr auto sum() -> typename std::common_type<decltype(Args)...>::type { using unused = int[]; using ReturnType = typename std::common_type<decltype(Args)...>::type; return [](decltype(Args)... args) // or since C++14 : (auto&&... args) { ReturnType result{}; (void)unused { 0, (result += args, 0)... }; return result; }(Args...); }
런타임에 있기 때문에 (이유 : 람다는 기본적으로
그러나 C ++ 17 람다는 암시 적constexpr
가 아닙니다. C ++ 17까지),test
의인스 턴 티아 온 불가능하다 (즉,test<sum<1, 2, 3>()>();
)로 이동합니다.constexpr
이기 때문에 달성 할 수 있습니다. C ++ 17에서 일반 접기 표현을 사용하므로 C ++ 11 또는 C ++ 14 컴파일러에 대한 OP의 관심사를 다루지 않으므로 단점이 다시 불필요합니다. <시간>†여기에서 자세히 읽어보십시오 : 가변형 템플릿 기본 클래스로의 통화를 확장하려면 어떻게해야합니까?
- 답변 # 4
rafix07의 솔루션이 실제로 정확하지만 실제 함수 매개 변수를 사용하지 않으려면 완전히 삭제하고 대신 템플릿 매개 변수를 사용하십시오.
template<int LastTerm = 0> constexpr auto sum() { return LastTerm; } template<int FirstTerm, int SecondTerm, int... Rest> constexpr auto sum() { return FirstTerm + SecondTerm + sum<Rest...>(); } template<int N> void test() { std::cout << "Sum of elements: " << N << " " << std::endl; } int main() { test<sum<1,5,7,6>()>(); }
- 답변 # 5
"고전적인"접근 방식은 재귀입니다 :
template <int...> struct Sum; template <> struct Sum<> : std::integral_constant<int, 0> { }; template <int N, int... Ns> struct Sum<N, Ns...> : std::integral_constant<int, N + Sum<Ns...>::value> { }; void test() { static_assert(Sum<8, 9, 10>::value == 27); }
관련 자료
- python - 요소를 그리는 방법?
- rest - 파일 다운로드 요청을 어떻게 찾습니까?
- google bigquery - 모든 값의 합계를 얻는 방법은 무엇입니까?
- big o - 이 코드의 공간 및 시간 복잡성을 어떻게 찾습니까?
- java - 배열의 행 합계를 어떻게 얻습니까?
- python - 목록에서 가장 많이 발생하는 두 문자열을 찾는 방법은 무엇입니까?
- 2D 목록 파이썬에서 목록의 동일한 요소를 찾는 방법
- java - Intellij Idea에서 패키지를 찾는 방법
- sorting - C의 행 합계로 행렬을 정렬하는 방법
- 자바의 텍스트 파일에서 중복을 찾는 방법
- c# - C # 30에서 특정 xml 요소를 찾는 방법
- android - Gradle로 APK 이름에 MD5를 추가하는 방법
- c++ - C ++ 20 std lib를 어떻게 구할 수 있습니까?
- sql - 신분증의 최신 2 개 기록을 얻는 방법
- javascript - 변수를 찾는 방법 - 반응 네이티브의 이름?
- c# - 탁구에서 변형을 무작위로 이동하려면 어떻게해야합니까?
- r - 각 ID에 대해 하나의 레코드를 가질 수 있도록 df를 재구성하는 방법
- Python으로 YouTube v3 API에서 JSON을 수정하려면 어떻게해야합니까?
- c - 이진 트리 경로 합계 찾기
- html - 텍스트 수정 방법
- c++ : 클래스 템플릿 T의 SFINAE에 대한 도움이 필요합니다.
- c++ : std::abs의 템플릿 버전
- c++ : 함수에 대한 상수 템플릿 인수
- c++ : 중첩 클래스의 메서드에 대한 반환 형식 추론
- C++의 char 템플릿 함수
- c++ : 기본 템플릿 인수를 사용하여 함수 템플릿에서 자동 추론된 반환 유형의 포인터 가져오기
- c++ : 단순 CRTP 케이스에 이름이 "XXX"인 구성원이 없습니다.
- c++ : initializer_list로 벡터를 초기화하기 위해 이동 생성자와 할당이 호출되지 않는 이유
- c++ : SFINAE 모호성
- c++ : cpp의 typedef에서 현재 유형 사용
접이식 사용 (c ++ 17 필요) :
<시간>C ++ 14에서 도우미 함수와 함께 재귀를 사용하십시오 :
실시간 데모
결과 19.