想象一下,我们有这样的模型:
class Container(models.Model):
name = models.CharField(max_length=60)
class Element(models.Model):
container = models.ForeignKey(Container, blank=True, null=True)
Run Code Online (Sandbox Code Playgroud)
Container是一个,Element是很多.
在Django管理,如果我添加一个StackedInline与model=Element该inlines对的Container型号联系:
class Inline(admin.StackedInline):
model = Element
class ContainerAdmin(admin.ModelAdmin):
inlines = (Inline,)
admin.site.register(Container, ContainerAdmin)
Run Code Online (Sandbox Code Playgroud)
我最终得到一个formset,允许我在Add Container表单中输入新 Element对象.
相反,我希望获得一个选择小部件,以选择现有的对象.
Element
没有引入额外的模型,这可能吗?
我们在代码库中发现了令人惊讶的行为,其中友谊关系未能应用.(目前仅与Clang编译,版本3.6)
我们可以将它减少到这个最小的例子.我们假设我们有以下模板类定义:
template <int>
class Element
{};
// Forward declaration of FriendBis
template <template <int> class> class FriendBis;
class Details
{
friend class FriendBis<Element>;
int mValue = 41;
};
template <template <int> class>
class FriendBis
{
public:
void useDetails(const Details &aDetails)
{
aDetails.mValue;
}
};
Run Code Online (Sandbox Code Playgroud)
在这里,Details声明FriendBis用其单个模板模板参数替换的实例化Element是它的friend.因此,以下客户端代码成功编译:
FriendBis<Element> fb1;
fb1.useDetails(Details());
Run Code Online (Sandbox Code Playgroud)
现在,让我们介绍一个额外的trait模板化类型,其目的是定义proto模板的模板别名Element:
struct trait
{
template <int N>
using proto = Element<N>;
};
Run Code Online (Sandbox Code Playgroud)
下面的客户端代码无法编译:
FriendBis<trait::proto> fb2;
fb2.useDetails(Details()); …Run Code Online (Sandbox Code Playgroud) 这是触发编译错误的最小示例:
#include <utility>
void foo(int, double, int)
{}
template <class... Args>
void post_forwarder(void(*fun)(Args..., int), Args&&... aArgs)
{
fun(std::forward<Args>(aArgs)..., 5);
}
int main()
{
post_forwarder(foo, 6, 6.1); // Compilation error on instantiation
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我怀疑这个问题与variadic模板参数在fixed int参数之前的函数类型中展开的事实有关,但如果是这种情况我就找不到合理的理由.
Clang 3.6报告的错误是:
error: no matching function for call to 'post_forwarder'
note: candidate template ignored: failed template argument deduction
Run Code Online (Sandbox Code Playgroud) 让我们假设我们有那些Django模型:
class Band(models.Model):
name = models.CharField(max_length=256, default="Eagles of Death Metal")
class Song(models.Model):
band = models.ForeignKey(Band)
Run Code Online (Sandbox Code Playgroud)
使用admin管理这些模型时,该band字段与WidgetDjango呈现为selecthtml元素相关联.
Django的管理员还在旁边添加了一个绿色加号图标select,单击它会打开一个弹出窗口,向用户显示Form添加新乐队.单击此弹出窗口中的" 保存"按钮时,新的波段名称将保存在数据库中,并自动分配给该select值.
我们依赖于每次select值更改时运行的一些JavaScript .它当前正在侦听change所述元素的事件,当用户直接在由菜单提出的菜单中单击某个值时,该元素可以正常工作select.
遗憾的是,当select通过Admin Popup功能填充时,似乎change事件未被触发select,因为我们的回调未被执行,即使元素的值实际已更改.
与用户直接从列表中单击值时相比,我们可以听到另一个事件来获取相同的行为吗?
我用来快速确定派生到基础转换是否合法的规则是检查在转换的上下文中是否有derivedIS-A base(即,derived提供对公共API的访问base).
它在C++ Primer(第5版)中更好地表达为:
对于代码中的任何给定点,如果
public可以访问基类的成员,则也可以访问派生到基础的转换,否则不可访问.
现在让我们假设一个类层次结构如下:
class Base
{
public:
int mem;
};
class Derived : protected Base
{
static void f(Derived *d)
{
d->mem; // OK, in this context, a Derived IS-A Base
Base *b = d;
}
};
int main()
{
Derived d;
//d.mem; // Compilation error : in this context a Derived IS-NOT-A Base
//Base *b = &d; // Compilation error too : consistent with the intuitive rule …Run Code Online (Sandbox Code Playgroud) 我们正在构建一个依赖于 Boost 的应用程序,编译会在 Boost 头文件 (tag_of.hpp) 中生成大量警告“不能重新声明类成员”。
为了避免垃圾邮件构建日志,我们决定将 Boost 标头作为系统标头包含在内:
target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${Boost_INCLUDE_DIRS})
Run Code Online (Sandbox Code Playgroud)
我们的理解是该命令应该将 Boost 包含目录放在-isystem编译器标志后面。然而,它没有做这样的事情,而是将它放在标题搜索路径中的“正常”包含目录旁边。
环境为CMake 3.0.0,为Xcode 5.1.1生成项目文件。这似乎是其他一些人的问题(请参阅此答案中的最后两条评论)。
有没有一种工作方法可以将标题作为系统包含在内?
编辑:刚刚在相同的环境中测试,将 CMake 更新到版本3.3.0,行为是相同的。
编辑:这是一个最小的例子,它显示了我的环境中的问题
cmake_minimum_required(VERSION 3.0)
find_package(Boost 1.49 COMPONENTS)
project(system_dependencies)
add_executable(${PROJECT_NAME} main.cpp)
target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${Boost_INCLUDE_DIRS})
Run Code Online (Sandbox Code Playgroud)
从此脚本生成的 Xcode 项目文件将 Boost 的路径放在构建设置中:Header search path,而不是将其附加在-isystem编译器标志后面。IDE发出的编译命令证实了这一点:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -x c++ -arch x86_64 -fmessage-length=0 -fdiagnostics-show-note-include-stack -fmacro-backtrace-limit =0 -Wno-trigraphs -fpascal-strings -O0 -Wno-missing-field-initializers -Wno-missing-prototypes -Wno-return-type -Wno-non-virtual-dtor …
我们将一部分无法找到正确语法的代码减少到最小的示例.
我们假设以下定义(不用担心"为什么";)
template <class>
class Element
{};
template <template <class> class>
class Client
{};
template <class>
struct TemplatedProvider
{
template <class T>
using element_template = Element<T>;
};
Run Code Online (Sandbox Code Playgroud)
现在,在C++ 11之后,我们可以使用类模板或类型别名模板来实例化Client模板.以下函数编译得很好:
void fun()
{
Client<Provider::element_template> client;
Client<TemplatedProvider<int>::element_template> clientBis;
}
Run Code Online (Sandbox Code Playgroud)
但是,当给出的模板参数Client是依赖名称时,我们在以下情况下找不到正确的语法:
template <class T>
void templatedFun()
{
Client<TemplatedProvider<T>::element_template> client;
}
Run Code Online (Sandbox Code Playgroud)
Clang(用3.6测试)发出以下编译错误:
template argument for template template parameter must be a class template or type alias template
Run Code Online (Sandbox Code Playgroud)
我们可以修复这种语法吗?
想象一下,我们有这个课程:
class Custom:
@classmethod
def get_choices(cls):
# use cls attributes to return a list
mapping = {"key": ... }
Run Code Online (Sandbox Code Playgroud)
我想返回的值相关联get_choices()来key.应该使用什么代码而不是占位符... ?
编辑:我想保持与上下文无关的问题(在我看来,这个要求很常见,但我可能有偏见).正如评论中所建议的那样,我将提供更多细节,因为我们似乎共同关注"最直接的代码":
我正在研究一个Django应用程序,我希望使用它们来保存枚举值的Models.在我看来,像一个自然的解决方案是创建一个enumeration.py模块,然后我可以class为每个枚举定义一个(该类至少有一个类方法来生成值集合).这是get_choices()示例中的内容.
现在,由于业务逻辑,我需要将这些选择映射到密钥.这个映射在逻辑上耦合到枚举,在同一个类中保持它们在一起似乎是一个很好的结构(给客户端代码统一和显式访问,以类名为前缀).
我按照这个答案中的建议开始学习Haskell .所以我只是实现了简单的列表函数,我偶然发现了编译器行为的不同,我无法向自己解释:
-- Impl 1
elementAt :: (Integral b) => [a] -> b -> a
elementAt xs id = xs !! (fromIntegral(id-1))
-- Impl 2
elementAt' :: (Num b) => [a] -> b -> a
elementAt' xs id = xs !! (id-1)
Run Code Online (Sandbox Code Playgroud)
使用以下签名:
fromIntegral :: (Integral a, Num b) => a -> b
(!!) :: [a] -> Int -> a
Run Code Online (Sandbox Code Playgroud)
我只在第二次实现时遇到错误elementAt'.
Could not deduce (b ~ Int)
from the context (Num b)
Run Code Online (Sandbox Code Playgroud)
如果我理解正确,则意味着运算符(!!)期望将Int实例作为其第二个参数(从签名中看到),但我们只保证提供的参数符合Num …
在我们的主项目中,构建管理推迟到CMake.对于我们不同的依赖项,一切都很顺利,包括Boost :: System,但是我们无法为Boost :: Serialization编译这个最小的例子.
# Untested with previous versions, yet should work
cmake_minimum_required(VERSION 2.8.11)
project(SerialCmake)
# Boost dependency
set(BOOST_ROOT CACHE PATH "Path to Boost library")
find_package(Boost 1.55 COMPONENTS serialization system)
# Create the target
add_executable(${PROJECT_NAME} main.cpp)
include_directories(${Boost_INCLUDE_DIR})
target_link_libraries(${PROJECT_NAME}
${Boost_LIBRARIES})
Run Code Online (Sandbox Code Playgroud)
#include <fstream>
#include <boost/archive/text_oarchive.hpp>
class Serializable
{
friend class boost::serialization::access;
public:
Serializable(int a): a(a)
{}
private:
template <class Archive>
inline void serialize (Archive &ar, const unsigned int version)
{
ar & a;
}
int a;
};
int main(int …Run Code Online (Sandbox Code Playgroud) 我们正在trivially_copiable从辅助存储中初始化(大型)对象数组,诸如此类的问题使我们对所实现的方法缺乏信心。
下面是一个最小的示例,试图说明代码中“令人担忧”的部分。也请在 Godbolt 上找到它。
让我们有一个trivially_copyable但不是default_constructible用户类型:
struct Foo
{
Foo(double a, double b) :
alpha{a},
beta{b}
{}
double alpha;
double beta;
};
Run Code Online (Sandbox Code Playgroud)
信任cppreference:
不存在潜在重叠子对象的普通可复制类型的对象是唯一可以使用 std::memcpy 安全复制或使用 std::ofstream::write()/std::ifstream 与二进制文件序列化的 C++ 对象::读()。
现在,我们想要将二进制文件读入动态数组中Foo。由于Foo不可默认构造,我们不能简单地:
std::unique_ptr<Foo[]> invalid{new Foo[dynamicSize]}; // Error, no default ctor
Run Code Online (Sandbox Code Playgroud)
使用未初始化的unsigned char数组作为存储。
std::unique_ptr<unsigned char[]> storage{
new unsigned char[dynamicSize * sizeof(Foo)] };
input.read(reinterpret_cast<char *>(storage.get()), dynamicSize * sizeof(Foo));
std::cout << reinterpret_cast<Foo *>(storage.get())[index].alpha …Run Code Online (Sandbox Code Playgroud) c++ ×7
c++11 ×3
templates ×3
cmake ×2
django ×2
class ×1
django-admin ×1
dom-events ×1
friend ×1
haskell ×1
include ×1
inheritance ×1
javascript ×1
linker ×1
python ×1
python-3.x ×1
types ×1
xcode ×1
xcode5 ×1