LINUX.ORG.RU

1
Всего сообщений: 40

с++: проверка наличия метода у типа.

Со времен С++11 есть возможность через SFINAE проверить наличие метода у типа. Но эта проверка громоздка и плохочитаема.

Вопрос появилось ли что либо новое с появлением новых стандартов, в том числе С++20? Или может кто знает, есть ли возможность прежние варианты упаковать в более лаконичный вид, используя вспомогательные классы которые запихнуть подальше в утилитные, оставив на виду только

HasMethod(T, myMethod, Res, Args...)::exists
?

Моя текущая версия проверки выглядит так, в отличие от упоминаемых в инете, она корректна для случаев если тестируемый класс является простым типом.

template<class T>
struct TestHasPack {

    template <class U>
    static void check_args( void(U::*)(Packer&) const );

    template <class U>
    static int detect(...);

    template <class U> static typename
    std::enable_if<
    std::is_same<
    decltype(check_args<U>(&U::pack)),void
    >::value>::type
    detect(T*);

    static constexpr bool exists =
    std::is_same<void,decltype(detect<T>((T*)nullptr))>::value;
};

 ,

victor79 ()

Как размножить собитие с переменным количеством параметров.

Пусть будут классы:

template <class F> struct Receptor;

// F это function<void(...)>

template <class F>
struct Sender {
    F use; // вызов sndr.use(a,b,c) должен размножится в list_use
    std::vector<Receptor<F>*> list_use;
};

template <class F>
struct Receptor {
    F process;
    Sender<F> * sender = nullptr;
    ~Receptor() { /* удаление из sender текущего Receptor */ }
};

Можно ли как либо сделать универсально Sender::use, что бы выполнив sndr.use(1,2,3) оно обошло все элементы list_use и выполнило вызов соотвествующих process с указанными параметрами? Т.е. размножило один вызов use на весь список.

 , ,

victor79 ()

C++ специализация шаблона для значения параметра шаблона своего типа

не могу понять, как сделать специализацию шаблонного метода нешаблонного класса (либо просто функции) по значению параметра шаблона своего типа?

пример:

enum class myType { FF, DD, GG }

template < myType >
void foo () {};

template <>
void foo < myType::DD > () {
...
}


так не получается — грит ошибка: идентификатор шаблона «getNumRemainedCards<lp::Board::boardState::RIVER>» для «constexpr int8_t lp::Deck::getNumRemainedCards( » не соответствует никакой декларации шаблона

 , , ,

safocl ()

запутался со специализацией шаблонного метода для шаблонного класса

Имеется что-то вроде такого шаблона:

template<int n>
struct foo_t{
	
	template<int m=n>
	int bar(){
		cout<<"call foo<"<<m<<">"<<endl;
		return m+bar<m-1>();
	};
};
И тут нужно явно специализировать вызов для bar<0>, а каким образом?

 ,

thunar ()

SFINAE по количеству аргументов у функции

Можете ржать, но я не осилил запилить SFINAE.

Темка такая. Мой код работает с некой библиотекой. В одной из версий у функции из этой библиотеки изменилось число аргументов. Было 3, а стало 4. Нужно написать код, который сможет работать с обеими версиями. Мне лень обмазывать код дефайнами и вносить изменения в сборочный скрипт.

Я хочу, чтобы шаблонная магия проверила сколько у функции аргументов и в зависимости от этого подставила нужное количество параметров. Накидал минимальный пример. Там у foo два аргумента, но компилятор залезает в первую шаблонную функцию, где передаётся три аргумента и умирает. Надо как-то отучить его туда ходить.

Стандарт C++14.

 , , ,

ox55ff ()

Шаблоны документов Thunar

В Thunar при клике на меню создать-> Документ Libreoffice Writer и других шаблонов выдается окно для ввода названия файла, я его ввожу и файл сохраняется на рабочем столе, а не открывается автоматически.

Как сделать так, чтобы при клике на меню шаблон сразу открывался, а не создавался документ на рабочем столе. Заранее благодарен за ответ.

 , , , ,

allon925 ()

Добавить в thunar пункты Libreoffice

Создал каталог Templates в домашнем каталоге и поместил туда 2 файла Libreoffice Writer .odt и .ott Пункты появились если я захожу в thunar открываю меню Файл -> Создать. Я вижу свои 2 пункта. Но когда я на рабочем столе кликаю правой кнопкой мыши у меня в меню Создать документ находится только одна строчка Пустой файл.

xfdesktop перегружал.

На рабочем столе: https://yadi.sk/i/y8a0mGwutETTSw

Меню файл в thunare: https://yadi.sk/i/saBd6pKokSmu8g

Папка в домашнем каталоге Templates: https://yadi.sk/i/TbXLdWp3jDXz0A

Из окна thunar меню создать: https://yadi.sk/i/VF2kjoml4o0bRg

Что нужно сделать чтобы пункты появлялись при клике на рабочем столе в меню Создать документ. Заранее благодарен за ответ.

 , , ,

allon925 ()

Специализация шаблона с константным значением

Добрый день всем.

Дано объявление шаблона:

template <typename T, T v>
struct Var
{
    using Type = T;

    static const Type value = v;
};

И есть его частичная специализация:

template <int N>
using Int = Var<int, N>;

Также есть обобшенная метафункция суммирования:

template <typename, typename>
struct Sum
{
    static void apply()
    {
        std::cout << "Common Sum()" << std::endl;
    }
};

Как написать специализацию этой функции именно для Int, если это возможно?

template <>
struct Sum<?, ?>
{
    static void apply()
    {
        std::cout << "Int Sum()" << std::endl;
    }
};

 , , ,

WaterLine ()

Если это не грустно с темами для Static Site Generators, то что тогда такое грустно вообще?

Больше сотни Static Site Generators для любых расовых предпочтений, но как и 5 лет назад — ни одной нормальной темы/темплейта.

Уже и octopress помер давно, hugo появился тоже относительно давно, но когда начинаешь смотреть на темы, включая коммерческие/премиум, которые я глянул первым делом — становится грустно.

Нактель они вообще нужны эти генератороподелки, если более-менее юзабельной, соответствующей сегодняшним реалиями (веб на мобилах), эстетично выглядящей темы не найти даже за деньги?

Кто видел «нормальную» тему для любого из живых static site generators — покажите пожалуйста.

Только просьба не давать ссылки на порты тем от html5up, спасибо.

// я не прошу за меня дизайн делать, дайте лишь нормальный скелет для кастомизации и т.п.

 ,

Bruce_Lee ()

Шаблоны, быдлокод, часть 1

Добрый день, начал разбираться с шаблонами в С++, сейчас знаю их хреново.

Есть тестовая программа.

Подскажите, пожалуйста, как надо изменить строку 57, либо конструктор класса Storage, чтобы заработала строка 57. В идеале я хочу просто иметь shared_ptr<T>, но при этом нужно уметь передавать параметры, спецефичные для <T>. Подскажите как это адекватно делать? Как я понял такая штука не прокатит (из-за разворачивания):

std::make_shared<T>(std::forward<Args>(args)...)

Может есть ещё замечания?

 ,

penetrator3000 ()

Синтаксис в Templates(необходимо добавить условие)

Подскажите, как правильно добавить условие:

{% if item.reg_price < 50 %} 
       {% price = item.reg_price + (item.reg_price/100*11,73)+ (item.reg_price/100*24,6) %} 
               <td>{{ price }}</td> 
{% elif 50 <= item.reg_price <= 500 %} 
       {% price = item.reg_price + (item.reg_price/100*12) + (item.reg_price/100*24,9) %} 
               <td>{{ price }}</td> 
{% elif item.reg_price < 500 %} 
       {% price = item.reg_price + (item.reg_price/100*11,75) + (item.reg_price/100*24,3) %} 
               <td>{{ price }}</td> 
{% endif %}

в templates:

{% elif target == 'reestr' %}
        <table class="table table-bordered table-condensed table" onselectstart="return false">
            <thead>
                <tr class="info">
                    <th class="text-center">Наименование</th>
                    <th class="text-center">Производитель</th>
                    <th class="text-center">Цена</th>
                </tr>
            </thead>
            <tbody>
                {% for item in item_list %}
                <tr class="active">
                    <td>{{ item.trade_name }}</td>
                    <td>{{ item.fabr_name}}</td>
                    <td>{{ item.reg_price }}</td> #здесь использовать условие
                </tr>
                {% endfor %}
            </tbody>
        </table>
        
Если заменить <td>{{ item.reg_price }}</td> условием, то начинают валиться ошибки.

Модель:

class TblReestr(models.Model):
    id = models.IntegerField(primary_key=True)  # AutoField?
    ean13 = models.CharField(max_length=50, blank=True, null=True)
    reg_price = models.DecimalField(max_digits=15, decimal_places=2, blank=True, null=True)
    trade_name = models.CharField(max_length=1000, blank=True, null=True)
    fabr_name = models.CharField(max_length=500, blank=True, null=True)
    reg_data = models.DateField(blank=True, null=True)
    mnn_name = models.CharField(max_length=250, blank=True, null=True)
    valuta_name = models.CharField(max_length=20, blank=True, null=True)
    num_prikaz = models.CharField(max_length=30, blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'tbl_reestr'

Views:

def search(request):
    q = request.GET['q']
    target = request.GET['target']
    title = request.GET['title']
    if target == 'brak':
        item_list = TblBrak.objects.filter(trade_name__icontains=q)
    elif target == 'reestr':
        item_list = TblReestr.objects.filter(trade_name__icontains=q)

Подскажите, как правильно в templates использовать такое условие.

 ,

PavelShturm ()

Ansible. Проблема с шаблоном

Имееться шаблон:

DATABASES = {
'default': {
'ENGINE': 'django.blabla.ops.{{ dbtype }}', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
'NAME': '{{ username }}', # Or path to database file if using sqlite3.
'USER': '{{ username }}',                      # Not used with sqlite3.
'PASSWORD: '{{ username }}',                  # Not used with sqlite3.

Сценарий должен его скопировать и подставить переменные. Но он материться ошибкой:

AnsibleError: template error while templating string: expected token 'name', got 'string'. String:

И после String мне шаблон пишет... Хелпаните, пожалуйста. Я уже и raw прописывал. Не могу понять что не так...

 ,

LYJEX ()

Типы для физических величин на C++: поругайте

Начал пилить некую систему типов для физических величин, где значение величины имеет семантику умножения безразмерного счётчика на абстрактную единицу измерения, чтобы не надо было каждый раз в публичных API вида SetFrequency(int freq) выяснять что же этот int хранит, а также чтобы не давало складывать метры с литрами и записывать результат в секунды (а также метры с километрами без должной конвертации первого или второго). Существующих велосипедов не нашёл, кроме разве Boost.Units, но это страшный overkill, надо чтобы было маленькое и в одном заголовке.

Базовая идея проста и описана в книжке Страуструпа в главе про <chrono> --

template<typename Rep, typename Period = std::ratio<1>>
class X
{
    Rep mCount;
};
 -- сохраняем значение безразмерного счётчика в фундаментальном типе Rep (int, double, etc), а десятичную приставку в виде рациональной дроби держим только в системе типов на этапе компиляции.

Код тут: https://github.com/Jajauma/SIUnits, содрано с std::chrono::duration, остатки libstdc++ ещё не вычистил полностью, так что на MSVC видимо работать не будет (а может и нигде не будет), главый шаблон SI::Units, для демонстрации там же определены типы Frequency и Length и нескучные пользовательские литералы типа _km, _mm и т.д.

 , ,

d_a ()

Chef переменные в темплейтах

Добрый день. Есть кукбук для Чифа по установке PHP (например). Он используется сразу для группы серверов (определенной роли). В этом кукбуке есть один template с конфигурацией настроек fpm пула. Вопрос, как для каждой ноды отдельно задавать переменные в этот темплейт. То есть, у меня 10 серверов, в кажом я хочу выделять разное количество памяти или воркеров, или назание пула. В темплейте есть переменные типа <%= @workers %>, <%= @pm.max_children %> итд.

 , ,

Banzay ()

Как объединить шаблоны и наследование

Попросили решить, но я не знаю как :(

Спасибо тому, кто подскажет идею.

Есть main.cpp, нужно чтобы он работал:

#include "quadrature.h"

#include <cmath>
#include <iostream>
#include <memory>
#include <string>

int main() {
    using F = decltype(cos);

    std::string input;
    std::cin >> input;
    std::unique_ptr<IntegrationMethod<F>> method;
    if (input == "rectangle")
        method.reset(new RectangleRule<F>);
    else
        method.reset(new TrapezoidalRule<F>);

    double x, y;
    std::cin >> x >> y;

    int n;
    std::cin >> n;

    std::cout << method->Integrate(cos, x, y, n) << "\n";
    std::cout << method->Integrate(sin, x, y, n) << "\n";
}

Я не знаю как именно реализовать три недостающих класса. Вот мой вариант, я знаю что он не правильный и не компилируется:

#ifndef __QUADRATURE_H__
#define __QUADRATURE_H__

template <typename F>
class IntegrationMethod
{
public:
	virtual double Integrate(F func, double x, double y, int n)
	{
		return 0;
	}
protected:
};

template <typename F>
class RectangleRule : public IntegrationMethod<F>
{
public:
	double Intergrate (F func, double x, double y, int n) override
	{
	    double value = 0;
		double step = (y - x)/n;
	    for (double i = x+step/2; i < y; i += step)
	    {
	        value += func(i);
	    }
	    value *= step;
	    return value;
	}
};

template <typename F>
class TrapezoidalRule : public IntegrationMethod<F>
{
public:
	double Intergrate (F func, double x, double y, int n) override
	{
	    double value = 0;
		double step = (y - x)/n;
	    for (double i = x; i < y; i += step)
	    {
	        value += func(i);
	    }
	    value *= step;
	    return value;
	}
};
#endif

 , ,

fsb4000 ()

libreoffice calc and templates

как в сабж создать шаблон, который будет использоваться для новой (не для всех новых, т.е не по умолчанию) таблицы и в которой при создании нового листа, этот лист будет открываться с шаблоном? Сейчас шаблон по умолчанию для всех таблиц, но новые листы открываются пустыми.

 ,

Wien_Lynx ()

Шаблонная магия С++. Как указать один из дефолтных параметров?

Доброго дня и новго года.

Камарады, есть вот такой вот, например, код

template <typename K, typename V, 
          typename VTrait = traits::simple<V>,
          typename SizeTrait = traits::default_size,
          typename MutexType = std::mutex
          >
class test {....};

То есть некоторый контейнер с шаблонными параметрами, часть из которых имеют значения по-умолчанию.

Теперь, если я хочу изменить только, например, mutex, то мне придется написать

template <typename K, typename V, typename MutexType>
using my_test = test<K, V, traits::simple<V>, traits::default_size, MutexType>;
Проблема в том, что мне нужно явно указать все параметры по-умолчанию, которые следуют до mutex, что не есть хорошо, поскольку само объявление класса test может поменяться и я хотел бы, чтоб во всех using оно так же поменялось.

Есть какой-то шаблонно-магический способ это решить?

Спасибо.

cast eao197, например...

 ,

seryoga ()

zabbix, Templates (шаблоны)

приветствую. осваиваю zabbix (3.2). по неосторожности удалил все templates в конфигурации и бэкапов не делал. их можно где-то скачать и затем импортировать в zabbix? не хочется переустанавливать все с нуля... заранее благодарю.

 , ,

ltaras ()

tuple<Args ...args>

помогите разобраться с шаблонизацией. есть класс, который занимается сериализацией данных для передачи по сети. использую msgpack (c++). заготовки методов выглядят так:

template <typename... Args >
void pack(Args... args) {
    msgpack::type::tuple < Args...> tuple(args...);
    msgpack::pack(m_sbuf, tuple);
    // кортеж в буфере
}
template <typename... Args >
msgpack::type::tuple < Args...> unpack(Args ...args){
   msgpack::unpacked msg = msgpack::unpack(m_sbuf.data(), m_sbuf.size());
   msgpack::type::tuple < Args...> tuple(args...);
   msg.get().convert(tuple);
   return tuple;
   // вынули кортеж из буфера.
}

использование

// тут все ок
pack( true, 12, std::string("hello"));
//а тут как-то сомнительно
int i; bool b; std::string s;
msgpack::type::tuple < bool, int, std::string> tuple = unpack(b, i, s);
сомнительно, а именно формально нужно передать параметры в unpack, чтобы работало в приведенном варианте. можно ли сделать что-то типа
unpack<Args...>
, ну т.е. без формальной передачи параметров.

 ,

conalex ()

Инстанцирование класса шаблоном с std::map с указателем на этот класс

Здравствуйте. Возникла проблема при написании одной из имплементаций Ахо-Корасик.

Вот ссылка сразу на код(пока что чисто полурабочая заготовка):http://pastebin.com/yc0LUDA0

Проблема вот в чём: обратите внимание на BorNode. У него внутри есть unordered_map<char, BorNode*>. Нужно это дело кастомизировать извне с помощью шаблонов. Что значит кастомизировать: мы можем менять тип контейнера - std::map/std::unordered_map, менять дефолтные std::hash, std::less у них и так далее, само собой, char тоже должны уметь менять на произвольный T.

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

Что я делал раньше: до того, как у меня были BorNode, у меня были просто size_t индексы нод в std::vector. И выглядело всё так:

template<typename T, typename Map, typename ResultCont = std::vector<std::vector<T>>>
class Base_Aho_Corasik{...}

template<typename T, typename Compare = std::less<T>, typename Alloc = std::allocator<std::pair<const T, size_t>>,
         typename ResultCont = std::vector<std::vector<T>>>
using Aho_Corasik = Base_Aho_Corasik<T, std::map<T, size_t, Compare, Alloc>, ResultCont>;

template<typename T, typename Hash = std::hash<T>, typename Pred = std::equal_to<T>,
         typename Alloc = std::allocator<std::pair<const T, size_t>>,
         typename ResultCont = std::vector<std::vector<T>>>
using Aho_Corasik_Hash = Base_Aho_Corasik<T, std::unordered_map<T, size_t, Hash, Pred, Alloc>, ResultCont>;

А как похожую вещь сделать с BorNode* вместо size_t я без понятия. У кого какие идеи? В выборе стандарта ограничений нет, можно использовать Boost.

 ,

zamazan4ik ()