2
constexpr int ipow(int x, int n) {
    return (n > 0) ? x * ipow(x, n - 1): 1;
}
template <char c>
constexpr int b3_helper() {
    static_assert(c < '3', "not a ternary digit");
    return c - '0';
}
template <char c, char... chars>
constexpr int b3_helper() {
    static_assert(c < '3', "not a ternary digit");
    return ipow(3, sizeof...(chars)) * (c - '0') + b3_helper<chars...>();
}
template <char... chars>
constexpr int operator"" _b3() {
return b3_helper<chars...>();
}
int main(){
    int i = 201_b3;
    return 0;
}

the compiler says

call to 'b3_helper' is ambiguous" at line 12;

how can I fix it? I find this problem when I learn the C++ programming language 4th. at page 560

greatwolf
  • 20,287
  • 13
  • 71
  • 105
Sherwin
  • 847
  • 1
  • 6
  • 16

1 Answers1

0

The ambiguity is because there are two equally good matches for a call like b3_helper<'1'> - the first function template can be matched with char c = '1' and the second can be matched with char c = '1' and ... being the empty parameter pack. To fix this, you can change the "induction" overload of the function to require two or more char's like this:

template <char c, char d, char... chars>
constexpr int b3_helper() {
    static_assert(c < '3', "not a ternary digit");
    return ipow(3, 1 + sizeof...(chars)) * (c - '0') + b3_helper<d, chars...>();
}
Pradhan
  • 16,391
  • 3
  • 44
  • 59