我有一个C++函数,它有5个参数,所有参数都有默认值.如果我传入前三个参数,程序将为最后两个参数分配一个默认值.有没有办法传递3个参数,并在中间跳过一个,给出值,比如第一,第二和第五个参数?
在下面的代码中,我为数组下标运算符提供了默认参数.
struct st
{
int operator[](int x = 0)
{
// code here
}
};
Run Code Online (Sandbox Code Playgroud)
但是,编译器生成了一个错误:
error: 'int st::operator[](int)' cannot have default arguments
int operator[](int x = 0)
Run Code Online (Sandbox Code Playgroud)
但是,如果我为函数调用运算符提供默认参数.
struct st
{
int operator()(int x = 0)
{
// code here
}
};
Run Code Online (Sandbox Code Playgroud)
它工作正常.
所以,我有一个问题:
c++ operator-overloading operators language-lawyer default-arguments
例如,像这样:
#include <cstdarg>
void my_function(int it=42, ...)
{
/* va_list/start/arg/end code here */
}
Run Code Online (Sandbox Code Playgroud)
上面的代码究竟在C++中意味着什么?它在G ++中编译得很好.请注意,我无法想象任何有用的情况,甚至它应该做的事情.我只是好奇.
我知道常见问题的答案如何指定指向重载函数的指针?:使用赋值或使用强制转换,并且每个其他C++教程都会使用这样的字符串(赋予或接受static_cast):
transform(in.begin(), in.end(), back_inserter(out), (int(*)(int)) std::toupper);
Run Code Online (Sandbox Code Playgroud)
或者像这样:
int (*fp)(int) = std::toupper;
transform(in.begin(), in.end(), back_inserter(out), fp);
Run Code Online (Sandbox Code Playgroud)
它整齐地选择了<cctype>过载std::toupper.
但这引出了一个问题:如何<locale>以类似的方式选择过载?
char (*fp2)(char, const std::locale&) = std::toupper;
transform(in.begin(), in.end(), back_inserter(out), fp2);
// error: too few arguments to function
Run Code Online (Sandbox Code Playgroud)
或者,更实际地,考虑有人试图std::stoi在算法中使用C++ 11 将字符串向量转换为整数向量:stoi有两个重载(string/ wstring),每个重载两个额外的默认参数.
假设我不想显式绑定所有这些默认值,我相信如果不在辅助函数或lambda中包含这样的调用就不可能这样做.是否有一个提升包装或TMP魔术以完全通用的方式为我做这件事?一个包装器可以call_as<char(char)>(fp2),call_as<int(const std::string&)>(std::stoi)甚至更可能,甚至可以写?
我想知道如果要指定第二个参数的值,如何使用默认参数调用函数.在下面的简单示例中,我展示了addTwo()接受两个参数.'first'参数有一个默认值,但'second'没有.如何调用此函数指定我要使用'first'的默认值,给定值为2的'second'?
调用addTwo(2)会抛出错误.
fun main(args: Array<String>) {
var sum = addTwo(1,2) // works fine
var nextSum = addTwo(2) // ERROR: No value passed for parameter second
}
fun addTwo(first: Int = 0, second: Int): Int {
return first + second
}
Run Code Online (Sandbox Code Playgroud) 目前的签名是
\ntemplate<class TypeData,typename TypeFunc>\nbool isPrime(const TypeData& n,TypeFunc fSqrt,bool debug = false)\nRun Code Online (Sandbox Code Playgroud)\n这与
\nstd::cout<<(isPrime(n,fSqrt)?"Positive":"Negative")<<'\\n';\nRun Code Online (Sandbox Code Playgroud)\n但是,我的意图是这样的
\ntemplate<class TypeData,typename TypeFunc>\nbool isPrime(const TypeData& n,TypeFunc fSqrt = nullptr,bool debug = false)\nRun Code Online (Sandbox Code Playgroud)\n或者
\ntemplate<class TypeData,typename TypeFunc>\nbool isPrime(const TypeData& n,TypeFunc fSqrt = NULL,bool debug = false)\nRun Code Online (Sandbox Code Playgroud)\n被称为
\nstd::cout<<(isPrime(n)?"Positive":"Negative")<<'\\n';\nRun Code Online (Sandbox Code Playgroud)\n由于函数内部有静态变量,因此不可能重载。
\n只有不同才应该为此function-templateclass TypeData提供不同的template-functions。
请帮助我使用正确的语法。如果 C++ 不支持这一点,我可以使用什么替代方法?
\n编译错误
\n为了TypeFunc fSqrt = nullptr
main.cpp:90:23: error: …Run Code Online (Sandbox Code Playgroud) 我刚刚开始阅读C++的初学者书.我有一些java经验(但是说过,我从来没有在java中使用默认参数,说实话)
所以,如上所述,我的问题是默认参数..
这是我正在使用的代码片段:
#include <iostream>
using namespace std;
//add declaration
int add(int a, int b);
int main (void)
{
int number1;
cout << "Enter the first value to be summed: ";
cin >> number1;
cout << "\nThe sum is: " << add(number1) << endl;
}
int add(int a=10, int b=5)
{
return a+b;
}
Run Code Online (Sandbox Code Playgroud)
我从g ++编译器得到的响应是:"函数'int add(int,int)'的参数太少了
我做错了吗?(我也用文字参数尝试过)
PS我似乎无法正常显示代码片段?系统有变化吗?
我的问题可以通过以下代码恢复:
template <typename T> struct C2;
template <typename T>
struct C1
{
template <typename Type,
template <typename Ti> class Container = C2>
void m() {}
};
template <typename T>
struct C2
{
template <typename Type = int,
template <typename Ti> class Container = C2> // <-- Here is the problem!
void m() {}
};
Run Code Online (Sandbox Code Playgroud)
gnu编译器版本4.8.1失败,并显示以下消息:
test-temp.C:16:47: error: invalid use of type ‘C2<T>’ as a default value for a template template-parameter
template <typename Ti> class Container = C2>
Run Code Online (Sandbox Code Playgroud)
它指的是方法C2 :: m的默认模板参数C2. …
由于 C++ 中的每个 lambda 函数都有自己的类型,并且 lambda 函数的类型可以用作模板参数的默认值,因此知道该类型在模板中的哪个时刻被替换是很有趣的。考虑一个 C++20 程序示例:
#include <concepts>
template<typename T = decltype([]{})>
using X = T;
template<typename T = X<>>
auto foo() { return T{}; }
int main() {
using T1 = decltype(foo());
using T2 = decltype(foo());
static_assert(!std::same_as<T1, T2>);
}
Run Code Online (Sandbox Code Playgroud)
这里类型别名定义中模板参数的默认类型X是 lambda 函数的类型 decltype([]{})。模板函数调用foo()返回该类型的值。
如果foo()程序中每次都出现新 lambda 类型的替换,则类型T1和T2必须是不同的,因为程序在static_assert. 并且此检查仅在 GCC 中通过。
在 Clang 和 MSVC 中,类型T1和T2是相同的,这意味着默认类型的替换不是每次都发生(而是在模板声明期间发生一次)。演示:https : //gcc.godbolt.org/z/dzYjf9r3q
根据标准,哪个编译器就在这里?
c++ ×9
c++11 ×2
templates ×2
arguments ×1
c++20 ×1
constructor ×1
function ×1
kotlin ×1
lambda ×1
operators ×1
optimization ×1
overloading ×1
pointers ×1