Здесь нет ничего неожиданного. Как объяснено в Как работает HashPartitioner? Spark использует хэш (ключ) по модулю количества разделов и неравномерное распределение, особенно для небольших наборов данных, не является неожиданным.
Ожидается также разница между Dataset
и RDD
, так как оба используют разные функции хеширования (то же самое).
Наконец,
В результате scala / spark генерирует неожиданный результат и создает меньше разделов
blockquote>- это не правильное наблюдение. Количество созданных разделов является точно запрошенным
scala> dfMyDataRepartitioned.rdd.getNumPartitions res8: Int = 5
, но пустые не будут видны в агрегации, потому что нет соответствующих значений.
] К сожалению, в настоящее время C++ не поддерживает использование строковых литералов (или реальных литералов) в качестве параметров шаблона.[
] [] Но перечитывая ваш вопрос, это то, что вы спрашиваете? Вы не можете сказать:[
] [foo <"bar"> x;
]
[]но можете сказать[
] [template <typename T>
struct foo {
foo( T t ) {}
};
foo <const char *> f( "bar" );
] C++ 20 fixed_string
+ "Типы классов в Шаблонных Параметрах Нетипа"
, По-видимому, предложение по этому было сначала принято, но затем удалено: "Строковые литералы как шаблонные параметры нетипа"
удаление состояло частично в том, потому что это, как считали, было достаточно легко сделать с другим предложением, которое было принято: "Типы классов в Шаблонных Параметрах Нетипа" .
принятое предложение содержит пример со следующим синтаксисом:
template <std::basic_fixed_string Str>
struct A {};
using hello_A = A<"hello">;
я попытаюсь обновить это с примером, который на самом деле говорит мне что-либо, после того как я вижу компилятор, который поддерживает его.
Redditor А также показал что следующие компиляции на ведущем устройстве GCC: https://godbolt.org/z/L0J2K2
template<unsigned N>
struct FixedString {
char buf[N + 1]{};
constexpr FixedString(char const* s) {
for (unsigned i = 0; i != N; ++i) buf[i] = s[i];
}
constexpr operator char const*() const { return buf; }
};
template<unsigned N> FixedString(char const (&)[N]) -> FixedString<N - 1>;
template<FixedString T>
class Foo {
static constexpr char const* Name = T;
public:
void hello() const;
};
int main() {
Foo<"Hello!"> foo;
foo.hello();
}
g++ -std=c++2a
9.2.1 от Ubuntu PPA не удается скомпилировать это с:
/tmp/ccZPAqRi.o: In function `main':
main.cpp:(.text+0x1f): undefined reference to `_ZNK3FooIXtl11FixedStringILj6EEtlA7_cLc72ELc101ELc108ELc108ELc111ELc33EEEEE5helloEv'
collect2: error: ld returned 1 exit status
Библиография: https://botondballo.wordpress.com/2018/03/28/trip-report-c-standards-meeting-in-jacksonville-march-2018 /
Наконец, EWG решила вытянуть ранее утвержденное предложение позволить строковые литералы в шаблонных параметрах нетипа, потому что более общее средство для разрешения типов классов в нетипе обрабатывает параметры по шаблону (который был просто утвержден), достаточно хорошая замена. (Это - изменение от последней встречи, когда казалось, что мы захотим обоих.) Основное различие - то, что теперь необходимо перенестись символьный массив в структуру (думайте fixed_string или подобный), и использование, что как шаблонный тип параметра. (Пользовательская литеральная часть P0424 все еще продвигается с соответствующей корректировкой позволенных шаблонных типов параметра.)
Это будет особенно прохладно с C++ 17 if constexpr
: , если / еще во время компиляции в C++?
Этот вид функции, кажется, соответствует потрясающему "constexpr все" предложения, которые вошли в C++ 20, такой как: это возможный использовать станд.:: строка в constexpr?
]Далее от ответа Нила: один из способов использования строк с шаблонами по вашему желанию - это определить класс трейтов и определить строку как трейт типа. [
] [#include <iostream>
template <class T>
struct MyTypeTraits
{
static const char* name;
};
template <class T>
const char* MyTypeTraits<T>::name = "Hello";
template <>
struct MyTypeTraits<int>
{
static const char* name;
};
const char* MyTypeTraits<int>::name = "Hello int";
template <class T>
class MyTemplateClass
{
public:
void print() {
std::cout << "My name is: " << MyTypeTraits<T>::name << std::endl;
}
};
int main()
{
MyTemplateClass<int>().print();
MyTemplateClass<char>().print();
}
]
[] печатает [
] [My name is: Hello int
My name is: Hello
] ] [] []Мне нужен класс, который принимает в конструкторе два параметра. Первый может быть либо int, либо double, либо float, так что, а второй всегда строковый литерал "моя строка"[
] [
template<typename T>
class demo
{
T data;
std::string s;
public:
demo(T d,std::string x="my string"):data(d),s(x) //Your constructor
{
}
};
]
[]Я не уверен, но это то, что вы хотите?[
].] [] [] строковый литерал "моя строка", так что, полагаю, const char * const[
] [
]На самом деле, строковые литералы с n видимыми символами имеют тип []const char[n+1][
]. [
#include <iostream>
#include <typeinfo>
template<class T>
void test(const T& t)
{
std::cout << typeid(t).name() << std::endl;
}
int main()
{
test("hello world"); // prints A12_c on my compiler
}
] ]EDIT: ok Заголовок вашего вопроса кажется вводящим в заблуждение[
] [] [] [] "Мне нужен класс, который принимает два параметра в своем конструкторе. Первый может быть либо int, либо double, либо float, так что, а второй всегда строковый литерал "моя строка", так что я думаю const char * const."[
] [
]Похоже, что вы пытаетесь достичь:[
] [template<typename T>
class Foo
{
public:
Foo(T t, const char* s) : first(t), second(s)
{
// do something
}
private:
T first;
const char* second;
};
]
[]Это сработает для любого типа, для первого параметра: []int[
], []float[
], []double[
], неважно.[
]Теперь, если вы действительно хотите ограничить тип первого параметра только []int[
], []float[
] или []double[
]; вы можете придумать что-нибудь более сложное, например[
template<typename T>
struct RestrictType;
template<>
struct RestrictType<int>
{
typedef int Type;
};
template<>
struct RestrictType<float>
{
typedef float Type;
};
template<>
struct RestrictType<double>
{
typedef double Type;
};
template<typename T>
class Foo
{
typedef typename RestrictType<T>::Type FirstType;
public:
Foo(FirstType t, const char* s) : first(t), second(s)
{
// do something
}
private:
FirstType first;
const char* second;
};
int main()
{
Foo<int> f1(0, "can");
Foo<float> f2(1, "i");
Foo<double> f3(1, "have");
//Foo<char> f4(0, "a pony?");
}
]
[]Если вы удалите комментарий в последней строке, вы фактически получите ошибку компилятора. [
] []Строковые литералы не допускаются C++2003[
] []ISO/IEC 14882-2003 §14.1:[
] [] [] [][]14.1 Параметры шаблона [][
] []Параметр нетипа шаблона должен иметь один из следующих (опциональноcv-квалифицированных) типов:[
] []- тип интеграла или перечисления, [
] []- указатель на объект или указатель на функцию, [
] []- ссылка на объект или ссылка на функцию, [
] []- указатель на член. [
] [
]ISO/IEC 14882-2003 §14.3.2:[
] [] [] [][]14.3.2 Аргументы шаблона, не относящиеся к типу [][
] [] - параметр-параметр шаблона, не относящийся к типу шаблона: [
] []- интегральное константно-выражение интегрального или перечислительного типа; или[
] []- имя параметра-параметра нетипа; или [
] []- адрес объекта или функции с внешней связью, включая шаблоны и шаблоны функций, но исключая нестатические члены класса, выраженные как & id выражение, где & является необязательным, если имя ссылается на функцию или массив, или если соответствующий шаблонный параметр является ссылкой; или[
] []- указатель на член, выраженный как описано в 5.3.1.[
]. [][Примечание: строковый литерал (2.13.4) не удовлетворяет требованиям ни одной из этих категорий и поэтому не является приемлемым шаблоном-аргументом[
]. [] [Пример: [
] [
template<class T, char* p> class X {
//...
X();
X(const char* q) { /* ... */ }
};
X<int,"Studebaker"> x1; //error: string literal as template-argument
char p[] = "Vivisectionist";
X<int,p> x2; //OK
]
[] [] []-окончательный пример] -окончательный комментарий]. [
] [
] И похоже, что это не изменится в грядущем C++0X, [] см. текущий проект 14.4.2 Шаблонные нетипичные аргументы [].[
].На основании ваших комментариев под ответом Нила, есть еще одна возможность:
#include <iostream>
static const char* eventNames[] = { "event_A", "event_B" };
enum EventId {
event_A = 0,
event_B
};
template <int EventId>
class Event
{
public:
Event() {
name_ = eventNames[EventId];
}
void print() {
std::cout << name_ << std::endl;
}
private:
const char* name_;
};
int main()
{
Event<event_A>().print();
Event<event_B>().print();
}
распечатать
event_A
event_B