명시 적으로 주어진 템플릿 매개 변수를 "추론"할 수없는 이유
Nov 19 2020
그 질문에서 오는 것 : SFINAE와 함께 열거 형 값 사용
구현하려고 시도했습니다.
enum Specifier
{
One,
Two,
Three
};
template <Specifier, typename UNUSED=void>
struct Foo
{
void Bar(){ std::cout << "Bar default" << std::endl;}
};
template <Specifier s , typename std::enable_if<s == Specifier::Two || s == Specifier::One, int>::type>
struct Foo<s>
{
void Bar(){ std::cout << "Bar Two" << std::endl; }
};
int main()
{
Foo< One >().Bar();
Foo< Two >().Bar();
}
실패 :
> main.cpp:130:8: error: template parameters not deducible in partial specialization:
130 | struct Foo<s>
| ^~~~~~
main.cpp:130:8: note: '<anonymous>'
그 아주 간단한 예를 고치는 방법? 나는 SFINAE를 좋아한다 :-)
답변
3 IlCapitano Nov 19 2020 at 12:48
enable_if
in Foo
의 템플릿 인수 목록을 넣으십시오 .
template <Specifier s>
struct Foo<s, typename std::enable_if<s == Specifier::Two || s == Specifier::One, void>::type>
// same as the default type used before ^^^^
데모 .
2 dfrib Nov 19 2020 at 12:57
오류에서 알 수 있듯이 템플릿 인수는 부분 전문화에서 추론 할 수 없습니다. 귀하의 예제에서는 특수화의 템플릿 매개 변수 목록에 SFINAE 구문을 배치하려고 시도했지만 특수화 선언 의 템플릿 인수 목록 (특화되는 클래스의)으로 이동해야합니다 .
template <Specifier S>
struct Foo<S, std::enable_if_t<(S == Specifier::Two) || (S == Specifier::One)>>
귀하의 예제에 적용 (조금 정리) :
#include <iostream>
#include <type_traits>
enum class Specifier {
One,
Two,
Three
};
template <Specifier, typename = void>
struct Foo {
static void bar() { std::cout << "bar default\n"; }
};
template <Specifier S>
struct Foo<S, std::enable_if_t<(S == Specifier::Two) || (S == Specifier::One)>> {
static void bar() { std::cout << "bar One or Two\n"; }
};
int main() {
Foo<Specifier::One>::bar(); // bar One or Two
Foo<Specifier::Two>::bar(); // bar One or Two
Foo<Specifier::Three>::bar(); // bar default
}
클래스 템플릿의 기본 템플릿에서 사용되지 않는 유형 템플릿 매개 변수의 이름을 지정할 필요는 없습니다 Foo
.
1 Deduplicator Nov 19 2020 at 12:49
템플릿 전문화의 템플릿 인수를 추론 할 수 없다는 것은 단순한 사실입니다.
당신이 그것을 필요로하는 것은 아닙니다.
템플릿 특수화를 변경하면됩니다.
template <Specifier s>
struct Foo<s, std::enable_if_t<s == Specifier::Two || s == Specifier::One, int>>
물론 결과 비록 std::enable_if_t
여기있는 int
대신 void
차종이 다소 쓸모.
또한 다른 사람들이 언급했듯이 개념을 사용하거나 적어도 requires
기본 템플릿의 추가 템플릿 인수 대신에 훨씬 더 편리합니다.