Почему указатели на функции могут быть `constexpr`?

Алгоритм Alphanum хорош, но он не соответствует требованиям для проекта, над которым я работаю. Мне нужно иметь возможность правильно сортировать отрицательные числа и десятичные знаки. Вот реализация, которую я придумал. Любая обратная связь будет высоко оценена.

public class StringAsNumberComparator implements Comparator {

    public static final Pattern NUMBER_PATTERN = Pattern.compile("(\\-?\\d+\\.\\d+)|(\\-?\\.\\d+)|(\\-?\\d+)");

    /**
     * Splits strings into parts sorting each instance of a number as a number if there is
     * a matching number in the other String.
     * 
     * For example A1B, A2B, A11B, A11B1, A11B2, A11B11 will be sorted in that order instead
     * of alphabetically which will sort A1B and A11B together.
     */
    public int compare(String str1, String str2) {
        if(str1 == null || str2 == null) {
            return 0;
        }

        List split1 = split(str1);
        List split2 = split(str2);
        int diff = 0;

        for(int i = 0; diff == 0 && i < split1.size() && i < split2.size(); i++) {
            String token1 = split1.get(i);
            String token2 = split2.get(i);

            if((NUMBER_PATTERN.matcher(token1).matches() && NUMBER_PATTERN.matcher(token2).matches()) {
                diff = (int) Math.signum(Double.parseDouble(token1) - Double.parseDouble(token2));
            } else {
                diff = token1.compareToIgnoreCase(token2);
            }
        }
        if(diff != 0) {
            return diff;
        } else {
            return split1.size() - split2.size();
        }
    }

    /**
     * Splits a string into strings and number tokens.
     */
    private List split(String s) {
        List list = new ArrayList();
        try (Scanner scanner = new Scanner(s)) {
            int index = 0;
            String num = null;
            while ((num = scanner.findInLine(NUMBER_PATTERN)) != null) {
                int indexOfNumber = s.indexOf(num, index);
                if (indexOfNumber > index) {
                    list.add(s.substring(index, indexOfNumber));
                }
                list.add(num);
                index = indexOfNumber + num.length();
            }
            if (index < s.length()) {
                list.add(s.substring(index));
            }
        }
        return list;
    }
}

PS. Я хотел использовать метод java.lang.String.split () и использовать «lookahead / lookbehind» для сохранения токенов, но я не мог заставить его работать с регулярным выражением, которое я использовал.

24
задан Coolwater 16 July 2016 в 15:53
поделиться

2 ответа

Как компилятор узнает, где в памяти будет находиться квадратный корень до выполнения программы?

Цепочка инструментов должна решить, куда поместить функции.

Это потому, что адрес относится к другому адресу в памяти?

Если созданная программа является перемещаемой или независимой от позиции тогда да, это так. Если программа не является ни тем, ни другим, адрес может быть даже абсолютным.

Почему при следующем запуске программы будут доступны точно такие же места памяти?

Поскольку пространство памяти виртуально .

6
ответ дан eerorika 16 July 2016 в 15:53
поделиться

Значение адреса назначается компоновщиком, поэтому компилятор не знает точного значения адреса.

cout << fp(5.0); 

Это работает, потому что он оценивается во время выполнения после того, как точный адрес был разрешен.

Как правило, вы не можете использовать фактическое значение (адрес) указателя constexpr, поскольку оно не известно во время компиляции.

Язык программирования С ++ Бьярна Страуструпа, 4-е издание , упоминает:

10.4.5 Выражения адресной константы

Адрес статически выделенный объект (§6.4.2), такой как глобальная переменная, является константой. Однако его значение присваивается компоновщиком, а не компилятором, поэтому компилятор не может знать значение такой адресной константы. Это ограничивает диапазон константных выражений указателя и ссылочного типа. Например:

   constexpr const char∗ p1 = "asdf";
   constexpr const char∗ p2 = p1;     // OK 
   constexpr const char∗ p2 = p1+2;   // error : the compiler does not know the value of p1 
   constexpr char c = p1[2];          // OK, c==’d’; the compiler knows the value pointed to by p1
17
ответ дан Srijith 16 July 2016 в 15:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: