我一直看到"鸭子打字"这个短语大肆渲染,甚至还遇到了一两个代码示例.我懒得忙着做自己的研究,有人可以简单地告诉我:

通过怀疑这种"新"结构的力量,我不是故意要发怒的,而且我不会因为拒绝做研究而避开这个问题,但我正在喋喋不休地谈论我所看到的所有关于这个问题的大肆宣传.最近.它看起来像没有打字(也就是动态打字),所以我没有立即看到优势.
附录:感谢目前为止的例子.在我看来,使用类似'O-> can(Blah)'的东西相当于进行反射查找(可能并不便宜),和/或与编译器可能说的(O是IBlah)大致相同能够检查你,但后者的优点是区分我的IBlah界面和你的IBlah界面,而其他两个没有.当然,对于每种方法都有很多微小的接口会变得混乱,但是那样可以检查很多单独的方法......
...所以我再也没有得到它.在一个全新的麻袋中,它是一个梦幻般的节省时间,还是同样的老东西?需要鸭子打字的例子在哪里?
请查看帖子末尾的最新更新.
特别是,请参阅更新4:变体比较诅咒
我已经看到配偶撞到墙上以了解变体是如何工作的,但从来没有想到我会有自己的糟糕时刻.
我已成功使用以下VBA构造:
For i = 1 to i
当这工作完全i是一个整数或者任何数值类型,从1迭代到原始值的i.我这样做的地方i是一个ByVal参数 - 你可能会说懒惰 - 让我自己声明一个新的变量.
然后当这个结构"停止"按预期工作时,我遇到了一个错误.经过一些艰难的调试后,我发现当它没有i被声明为显式数字类型时,它的工作方式不同,但是a Variant.问题有两个:
1- For和For Each循环的确切语义是什么?我的意思是编译器执行的操作顺序是什么,顺序是什么?例如,限制的评估是否在计数器的初始化之前?在循环开始之前,这个限制是否被复制并"修复"了?等等.同样的问题适用于For Each.
2-如何解释变体和显式数字类型的不同结果?有人说变体是一个(不可变的)引用类型,这个定义可以解释观察到的行为吗?
我已经为涉及和语句的不同(独立)场景准备了MCVE,并结合了整数,变体和对象.令人惊讶的结果促使明确定义语义,或者至少检查那些结果是否符合定义的语义.ForFor Each
欢迎所有见解,包括解释一些令人惊讶的结果或其矛盾的部分见解.
谢谢.
Sub testForLoops()
Dim i As Integer, v As Variant, vv As Variant, obj As Object, rng As Range
Debug.Print vbCrLf & "Case1 i --> i ",
i …Run Code Online (Sandbox Code Playgroud) 许多人使用C++ 17/boost变体的模式看起来与switch语句非常相似.例如:( 来自cppreference.com的片段)
std::variant<int, long, double, std::string> v = ...;
std::visit(overloaded {
[](auto arg) { std::cout << arg << ' '; },
[](double arg) { std::cout << std::fixed << arg << ' '; },
[](const std::string& arg) { std::cout << std::quoted(arg) << ' '; },
}, v);
Run Code Online (Sandbox Code Playgroud)
问题是当您在访问者中输入错误的类型或更改变体签名时,但忘记更改访问者.您将获得错误的lambda,通常是默认的lambda,而不是获得编译错误,或者您可能会得到一个您没有计划的隐式转换.例如:
v = 2.2;
std::visit(overloaded {
[](auto arg) { std::cout << arg << ' '; },
[](float arg) { std::cout << std::fixed << arg << ' '; } // oops, this won't …Run Code Online (Sandbox Code Playgroud) 有谁知道如何返回在VBA中传递给它的(Variant)变量的维数?
例如,假设您要在C++中实现电子表格Cell.单元格可以是字符串,数字,也可以是空的.忽略其他情况,例如它是一个公式.
在Haskell中,您可能会执行以下操作:
data Cell = CellStr String | CellDbl Double | None
Run Code Online (Sandbox Code Playgroud)
什么被认为是在C++中实现它的当前"最佳实践"?在带有类型指示符的结构中使用union,还是其他什么?
以下代码:
variant<string> x = "abc";
cout << get<string>(x) << "\n";
Run Code Online (Sandbox Code Playgroud)
在g ++(版本7.2)下正常工作.但是,当使用libstdc ++在clang ++(版本5.0)下编译时,我在get方法中得到以下错误:
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/7.2.0/../../../../include/c++/7.2.0/variant:238:46: fatal error: cannot cast 'std::variant<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >' to its private base class 'std::__detail::__variant::_Variant_storage<false, std::
__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >'
return __get(std::in_place_index<_Np>, std::forward<_Variant>(__v)._M_u);
Run Code Online (Sandbox Code Playgroud)
这是编译器错误,还是我的代码以任何方式违法?
我是 android 开发的新手,我开始在网上购买的项目上从头开始开发,按照文档,我遇到了一个错误,说没有找到“应用程序”的变体。检查构建文件以确保至少存在一种变体。
这是 build.gradle 代码
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.1"
defaultConfig {
applicationId "com.app-10.app"
minSdkVersion 23
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.vectordrawable:vectordrawable:1.0.1'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
// Third Party Libraries
//Glide library for image fetching from the web
implementation 'com.github.bumptech.glide:glide:4.9.0' …Run Code Online (Sandbox Code Playgroud) 在计算机科学中,有两个难题:缓存失效,命名和一个错误。
这是关于第二个问题的:命名事物。
我在寻找这种技术或类型是否已经在其他地方使用并且有名称。 dichotomy是一个不错的名字,但那bools_at_compile_time是一个可怕的名字。
using dichotomy_t = std::variant<std::false_type, std::true_type>;
// (or a struct that inherits from that, and overloads operator bool())
constexpr dichotomy_t dichotomy( bool b ) {
if (b) return std::true_type{};
return std::false_type{};
}
template<class F, class...Bools>
constexpr auto bools_at_compile_time( F&& f, Bools...bools ) {
static_assert( (std::is_same<Bools, bool>{} && ...) );
return std::visit( std::forward<F>(f), dichotomy(bools)... );
}
Run Code Online (Sandbox Code Playgroud)
dichotomy_t是true和false之间的变体。其运行时表示为0或1。
这可以让您做的是:
auto foo( bool x, bool y ) { // <-- x and …Run Code Online (Sandbox Code Playgroud) 这个答案描述了如何流式传输独立的std::variant.但是,它std::variant存储在一个时似乎不起作用std::unordered_map.
以下示例:
#include <iostream>
#include <string>
#include <variant>
#include <complex>
#include <unordered_map>
// https://stackoverflow.com/a/46893057/8414561
template<typename... Ts>
std::ostream& operator<<(std::ostream& os, const std::variant<Ts...>& v)
{
std::visit([&os](auto&& arg) {
os << arg;
}, v);
return os;
}
int main()
{
using namespace std::complex_literals;
std::unordered_map<int, std::variant<int, std::string, double, std::complex<double>>> map{
{0, 4},
{1, "hello"},
{2, 3.14},
{3, 2. + 3i}
};
for (const auto& [key, value] : map)
std::cout << key << "=" << value …Run Code Online (Sandbox Code Playgroud) 我最近将gcc和g ++更新到版本7.2.我想尝试一下std::experimental::any,std::variant特别是,我在QtCreator中使用Qt 5.9.1.
到目前为止,我已经在项目文件中写了这个:
CONFIG += c++17
Run Code Online (Sandbox Code Playgroud)
我在正确的位置添加了正确的标题:
#include <variant>
#include <experimental/any>
Run Code Online (Sandbox Code Playgroud)
任何工作都很好,没有问题.但是,当我包含变体头文件时,我收到此错误:
/usr/include/c++/7/bits/c++17_warning.h:32: error: #error This file requires compiler and library support for the ISO C++ 2017 standard. This support must be enabled with the -std=c++17 or -std=gnu++17 compiler options.
Run Code Online (Sandbox Code Playgroud)
#error此文件需要编译器和库支持\ ^ ~~~~
我在项目文件中尝试过各种各样的东西,这里是完整列表:
CONFIG += c++17
Run Code Online (Sandbox Code Playgroud)
&
CONFIG += c++1z
Run Code Online (Sandbox Code Playgroud)
&
QMAKE_CXXFLAGS += -std=c++17
Run Code Online (Sandbox Code Playgroud)
&
QMAKE_CXXFLAGS += -std=c++1z
Run Code Online (Sandbox Code Playgroud)
&
CONFIG += c++17
QMAKE_CXXFLAGS += -std=c++17
Run Code Online (Sandbox Code Playgroud)
&
CONFIG += c++1z
QMAKE_CXXFLAGS += -std=c++1z
Run Code Online (Sandbox Code Playgroud)
&
CONFIG …Run Code Online (Sandbox Code Playgroud) variant ×10
c++ ×6
c++17 ×5
vba ×2
android ×1
boolean ×1
build ×1
clang++ ×1
dimensions ×1
duck-typing ×1
excel ×1
for-loop ×1
interface ×1
polymorphism ×1
qt-creator ×1
unions ×1
vb6 ×1
visitor ×1